首页 > 其他分享 >P7221 [JSOI2010] 蔬菜庆典 题解

P7221 [JSOI2010] 蔬菜庆典 题解

时间:2023-02-24 13:33:44浏览次数:47  
标签:JSOI2010 P7221 int 题解 sum step num tac 节点

本题解在求无解的情况下优化了下。

通过分析样例,我们可以发现如果一个节点有多个 Dlihc,那么这些 Dlihc 对应的权值必须一样,否则可以无限延伸下去。

因为一号节点没有 Tnerap,所以一号节点一定不能更新,加上关系成树型结构那我们可以看成一个根节点把一棵树分成了几个子任务。

若子树不为链,就一定有一个节点有多个 Dlihc,设这个节点为 \(x\)。

那如果要判断无解:

1、\(x\) 的子节点有权值不相同。

2、\(x\) 的子节点相同,且子节点有子节点,并且此子任务中有节点可以更新。

证明:第一个易证,第二个若 \(x\) 的子节点有子节点,代表 \(x\) 的子节点可以更新。若子节点的子节点的权值与 \(x\) 节点权值加起来为子节点权值相同,才有可能有解。若此时 \(x\) 节点和子节点的子节点更新,那么必定无解。若不能更新,那可能有解,但若 \(x\) 的父节点与子节点的子节点的子节点可以更新,那无解。综上,只要这个字任务的树中有节点可以更新,那么就无解。

然后就是求答案,首先如果一个子任务不为链且 \(x\) 的子节点有子节点,那么无法更新,直接累加即可。

若不为链但 \(x\) 的子节点无子节点,由于 \(x\) 的子节点无法更新,可以取任意一个子节点即可,化作为链求解。

求解过程与其他人差不多,对链上的数进行查分,将差分后的数从大到小排序后,求所有的差分前缀和即可。

程序中先将所有点的初始值加起来,如果要进行差分加排序操作,再减去。

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#define int long long
using namespace std;
const int N=2e5+5;
int n,pre[N],num[N],ans,sum[N],pef[N];
vector<int>suf[N];
bool flag,lim,flag2;
//flag 代表是否为不是链的情况,
//lim 代表这棵树是否能更新,
//flag2 代表x的子节点是否有子节点。
bool dfs(int x,int step)
{
	sum[step]=num[x]-num[pre[x]];
	pef[step]=x;
	int len=suf[x].size();
	if(len==0&&!flag)
	{
		sort(sum+1,sum+1+step);
		int tac=num[1];
		for(int i=step;i>0;i--)tac+=sum[i],ans+=tac-num[pef[i]];
		return true;
	}
	if(flag==1&&len!=0)flag2=1;
	if(flag2==1&&lim==1)return false;
	if(len>1)flag=1;
	bool ss=1;
	for(int i=0;i<len;i++)
	{
		if(num[pre[x]]+num[suf[x][i]]!=2*num[x])lim=1;
		ss&=dfs(suf[x][i],step+1);
		if(num[suf[x][0]]!=num[suf[x][i]])return false;
	}
	if(len>1&&!flag2)
	{
		sort(sum+1,sum+1+step+1);
		int tac=num[1];
		for(int i=step+1;i>0;i--)tac+=sum[i],ans+=tac-num[pef[i]];
	}
	return ss;
}
signed main()
{
	while(1)
	{
		scanf("%lld",&n);
		if(n==0)break;
		ans=0;
		for(int i=1;i<=n;i++)suf[i].clear(),scanf("%lld%lld",&pre[i],&num[i]),suf[pre[i]].push_back(i),ans+=num[i];
		int len=suf[1].size();
		bool st=1;
		for(int i=0;i<len;i++)
		{
			flag=flag2=lim=0;
			if(!dfs(suf[1][i],1))st=0;
		}
		if(!st)printf("+inf\n");
		else printf("%lld\n",ans);
	}
	return 0;
}

标签:JSOI2010,P7221,int,题解,sum,step,num,tac,节点
From: https://www.cnblogs.com/gmtfff/p/p7221.html

相关文章

  • P3195 [HNOI2008]玩具装箱 题解
    首先先写dp方程非常简单\(\mathit{f}_{i}=\min(\mathit{f}_{j}+(\mathit{c}_{i}+i-j-1-L-\mathit{c}_{j})^2)\)(其中\(\mathit{c}_{i}\)表示长度前缀和)然后发现括号......
  • U259394 Gmt丶FFF 的基环树 题解
    题目链接:传送门之所以评黑,是因为实在是太难调了。(又回调了)。对于有$40%$的数据,$n\le3000$,这部分我们可以暴力删边,然后暴力求直径即可。那么对于$100%$的数据:首先......
  • P3977 [TJOI2015]棋盘 题解
    前制知识引导状态压缩动态规划:[P1896[SCOI2005]互不侵犯](https://www.luogu.com.cn/problem/P1896)矩阵加速优化:[P1962斐波那契数列](https://www.luogu.com.cn/prob......
  • vscode格式化和保存代码与eslint有冲突问题解决(亲测有效)
    1.问题描述vscode安装了eslint插件,在使用Vue的时候格式化和保存代码都会爆红2.原因因为在使用Vue进行开发我们一般都安装了Vetur插件来对.vue文件进行处理,Vetur自带了......
  • 云原生|kubernetes|CKA真题解析-------(6-10题)
    第六题:service配置 解析:考察两个知识点:deployment控制器内的port命名暴露一个pod内的端口到新建的服务内的这里有一个需要注意的地方,没有告诉你deployment控制器在哪个name......
  • Windows 技术篇 - 远程桌面连接不保存密码、每次都要输入密码问题解决
    https://blog.csdn.net/qq_38161040/article/details/120013883通过 gpedit.msc 打开本次组策略编辑器。选择 模板管理-系统-凭据分配-允许分配保存的凭据用......
  • 【题解】ARC156 A-C
    神仙的ARC。A.Non-AdjacentFlip题目分析:就是一个分类讨论,主要就是讨论一下只有\(2\)个\(1\)的情况。自己手模一下应该很好理解。代码:点击查看代码#include<b......
  • [luogu P4705玩游戏] 题解
    P4705玩游戏题解题意概括给出两个序列\(a_0,a_2,\cdotsa_{n-1}\),\(b_0,b_2,\cdotsb_{m-1}\),从两个序列中各等概率的选出两个数\(a_i,b_j\),对于\(k\in[1,t]\)......
  • 【微元贡献法 & 连续段 dp】「JOI Open 2016」摩天大楼 - 题解
    「JOIOpen2016」摩天大楼-题解注意到绝对值求和的形式,比较自然地想到将权值\(a\)排序以规避绝对值,下文默认\(a\)按从小到大排序,且插入元素的顺序亦为从小到大。......
  • 关于Android Studio的文件建立不显示问题解决
    这个很好解决,什么原理不太清楚,在AndroidStudio界面下建立目录不显示,切换为project就可以显示了 ......