首页 > 其他分享 >P2230 Tinux系统 题解

P2230 Tinux系统 题解

时间:2023-10-27 20:55:41浏览次数:42  
标签:文件 题解 tr pos Tinux 插入 P2230 times 目录

传送门

提供一种基于贪心的解法。

首先是将 \(p\) 从小到大排序

考虑到该系统是一棵树,所以对于系统中的每个点,我们记:

\(tr_{son}\) 表示该点(目录)的儿子的位置

\(tr_{fa}\) 表示该点(目录)的父亲的位置

\(tr_{siz}\) 表示该点(目录)包含的点的个数

\(tr_{cnt}\) 表示该点(目录)有多少个儿子

\(tr_{val}\) 表示该点(目录)的 \(p\) 值

考虑对于现在系统中已经有了 \(x\) 个文件,现在要插入第 \(x+1\) 个文件。

考虑这个文件可以插入到的地方以及对答案贡献:

操作 \(1\)、插入到原有目录中。

贡献为:\((\sum\limits_{pos \in tr} tr_{val} \times (tr_{siz}*2+1))+p_{pos}\)

即新文件所有父亲目录的 \(p_i\) 乘上两倍该目录的点的个数加一,然后再加上新文件的 \(p_i\)

操作 \(2\)、将该位置的文件变成目录,然后向这个目录中插入原位置文件和新文件。

贡献为:\((\sum\limits_{pos \in tr} tr_{val} \times (tr_{siz}*2+1))+p_1+p_2+p_{pos} \times 3\)

即该位置文件所有父亲目录的 \(p_i\) 乘上两倍该目录的点的个数加一,然后加上该文件的 \(p_i\) 乘三,再加上 \(p_1\) 和 \(p_2\)

这些不难推导,可以结合样例推导

考虑其正确性:

1、若要将新文件插入到一个目录,一定会将新文件插在 \(p_i\) 尽量小的地方,而将 \(p\) 从小到大排序之后,一定会先插完 \(p_{1 \sim i-1}\),再插 \(p_i\)

2、对于一个空位置,新文件一定是直接插在该位置比在该位置建目录,再插入到目录中更优

3、无论是插入到哪里,设该次插入对答案造成的贡献为 \(t\),则新的可以插入的位置对答案造成的贡献不会小于 \(t\)

对于第三个性质的证明,我们只在整理将先进行操作 \(2\) 再进行操作 \(1\) 仍满足性质 \(3\):

若再新建的目录下插入第 \(3\) 个文件,则相比操作二, \(\sum\) 中多出来的就是 \(p_{pos} \times (pos_{siz}+1)\) 即,\(p_{pos} \times 5\),而再加上 \(p_3\),显然 \(p_{pos} \times 5+p_3>p_{pos} \times 3 p_1+p_2\)

其他同理

基于这三个性质,我们可以如此操作:

对该系统进行深搜。

对于一个目录,考虑它可以加入的最小的 \(p_i\) 对答案的贡献,加入数组 \(a\) 中

对于一个文件,考虑它变成目录再插入文件对答案的贡献,加入数组 \(a\) 中

然后将 \(a\) 从小到大排序

将最小的加入答案,并更改该系统即可

注意特别判断在 \(root\) 插入的情况

上代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int n,k,p[N],ans;
struct jgt
{
	int son[155];
	int siz,val,cnt,fa;
}tr[N*2];
int tot;
struct jgt1
{
	int x,pos;
}a[N*2];
int idx;
bool cmp(jgt1 t1,jgt1 t2)
{
	return t1.x<t2.x;
}
void dfs(int wz,int sum)
{
	if(wz==0)
	{
		for(int i=1;i<=tr[wz].cnt;i++)
			dfs(tr[wz].son[i],0);
		if(tr[wz].cnt!=k)
		{
			a[++idx].pos=wz;
			a[idx].x=p[tr[wz].cnt+1];
		}
	}
	else
	{
		if(tr[wz].cnt==0)
		{
			a[++idx].pos=wz;
			a[idx].x=sum+tr[wz].val*3+p[1]+p[2];
		}
		else if(tr[wz].cnt==k)
		{
			for(int i=1;i<=k;i++)
				dfs(tr[wz].son[i],sum+tr[wz].val*(tr[wz].siz*2+1));
		}
		else
		{
			a[++idx].pos=wz;
			a[idx].x=sum+tr[wz].val*(tr[wz].siz*2+1)+p[tr[wz].cnt+1];
			for(int i=1;i<=tr[wz].cnt;i++)
				dfs(tr[wz].son[i],sum+tr[wz].val*(tr[wz].siz*2+1));
		}
	}
}
void get(int wz)
{
	tr[wz].siz++;
	if(tr[wz].fa!=0) get(tr[wz].fa);
}
void add(int wz)
{
	if(wz==0)
	{
		tr[wz].cnt++;
		int shu=tr[wz].cnt;
		tr[wz].son[shu]=++tot;
		tr[tot].val=p[shu];
		tr[tot].fa=wz;
		return ;
	}
	if(tr[wz].cnt!=0)
	{
		tr[wz].cnt++;
		tr[wz].siz++;
		int shu=tr[wz].cnt;
		tr[wz].son[shu]=++tot;
		tr[tot].val=p[shu];
		tr[tot].fa=wz;
		if(tr[wz].fa!=0) get(tr[wz].fa);
		return ;
	}
	if(tr[wz].cnt==0)
	{
		tr[wz].cnt=2;
		tr[wz].siz=2;
		tr[wz].son[1]=++tot;
		tr[tot].val=p[1];
		tr[tot].fa=wz;
		tr[wz].son[2]=++tot;
		tr[tot].val=p[2];
		tr[tot].fa=wz;
		if(tr[wz].fa!=0) get(tr[wz].fa);
		return ;
	}
}
int main()
{
	scanf("%d %d",&n,&k);
	for(int i=1;i<=k;i++)
		scanf("%d",&p[i]);
	sort(p+1,p+k+1);
	for(int i=1;i<=n;i++)
	{
		idx=0;
		dfs(0,0);
		sort(a+1,a+idx+1,cmp);
		ans+=a[1].x;
		add(a[1].pos);
	}
	printf("%d\n",ans);
	return 0;
}

标签:文件,题解,tr,pos,Tinux,插入,P2230,times,目录
From: https://www.cnblogs.com/pengchujie/p/17793128.html

相关文章

  • YACS 2023年10月月赛 甲组 题解
    目前只有T2,其他题目我在看。题目链接1题目链接2题目链接3T2很简单的一道题,将图分为若干个连通块,然后分别求最小生成树。从货车运输中得到的结论,最小生成树等价于最小边权上限生成树,也就是它也能够保证选出边中最大的边权最小。而题目中明确说了这个最小生成树的权值是其中......
  • [NOI2010] 超级钢琴 题解
    [NOI2010]超级钢琴题解说点闲话原本不想写这个题解的但是看到我的代码居然长度为2048B->刚好2KiB,然后还跟题号相同QAQ题目翻译给你一段序列,求出其中从第\(1\)大到第\(k\)大的子区间的和。思路解析首先可以想到一个简单的暴力,对于每一个区间开头\(i\),和区间结尾\(j\),都求......
  • 2023 CSP-J2 T1,2,3题解
    今年的\(CSP−J\)对本蒟蒻来说有点难度。。。A[CSP-J2023]小苹果题目描述小Y的桌子上放着\(n\)个苹果从左到右排成一列,编号为从\(1\)到\(n\)。小苞是小Y的好朋友,每天她都会从中拿走一些苹果。每天在拿的时候,小苞都是从左侧第\(1\)个苹果开始、每隔\(2\)个......
  • [TJOI2013] 松鼠聚会 题解
    [TJOI2013]松鼠聚会题解切比雪夫距离切比雪夫距离指的是在平面上的两个点\((x_1,y_1)\),\((x_2,y_2)\)之间横纵坐标之差绝对值中的大者。用公式表示则是\(f(a,b)=max(|x_a-x_b|,|y_a-y_b|)\)。切比雪夫距离与曼哈顿距离之间可以相互转换切比雪夫—>曼哈顿:\((x_1,y_1)\),\((x......
  • [NOIP 2013提高组]货车运输 题解
    [NOIP2013提高组]货车运输题解前置知识Kruskal重构树(内含讲解)+任意一种LCA题目翻译\(n\)座城市,\(m\)条道路,\(q\)次询问,每次求两个点\(x,y\)之间所有路径的最小值的最大值。题目分析其实学了Kruskal重构树差不多看到这个题目就知道怎么写了。其实就是Kruskal重构树的板子,......
  • 问题解决
    pip源问题解决使用pip安装pytorch出现WARNING:Retrying(Retry(total=4,connect=None,read=None,redirect=None,status=None))报错使用换源解决问题pip3configlistpip3configsetglobal.index-urlhttps://mirrors.aliyun.com/pypi/simple/pip3configlist国内......
  • 第四章苏格拉底问答、实践过程截图、遇到问题解决问题截图,代码链接
    代码#include<stdio.h>#include<stdlib.h>#include<pthread.h>#defineN4intA[N][N],sum[N];void*func(voidarg){intj,row;pthread_ttid=pthread_self();row=(int)arg;printf("Thread%d[%lu]computessumofrow%d\n"......
  • Python打不开问题解决方案大全
    在使用Python进行编程开发的过程中,我们不可避免会遇到Python打不开的问题。这些问题可能是由于环境配置、包管理和依赖文件等问题所导致的,但不管是何种原因,我们都需要解决它们才能顺利地进行工作。本文将从多个方面为大家详细介绍Python打不开问题的解决方法。一、Python环境配......
  • Acwing393. 雇佣收银员 题解 差分约束
    题目链接:https://www.acwing.com/problem/content/description/395/解题思路:差分约束。为了方便起见,定义第\(i\)个时间段为\(i-1:00\)到\(i:00\)首先,为了方便开一个额外的点,令\(R_i\)对应为题目中的\(R(i+1)\),即\(R_i\)表示\(i-1:00\)到\(i:00\)这个时间段的最小需求......
  • AnyCAD程序无法启动的问题解决方法
    在某些电脑上会出现基于AnyCAD开发的程序无法启动的问题,如:System-ArgumentEcception:Pleasecheckthedependendes解决方法安装最新的VS运行时库,如VS2022:微软官方下载地址:x64:vc_redist.x64.exeSystem.AccessViolationException:"Attemptedtoreadorwriteprotectedmemor......