CF Round #633

CF Round #633

A.找规律

动手画一画

https://www.luogu.com.cn/record/32752272

B.构造,数学

给定一个n个数,求他们组成的一个序列

使得该序列中前后两者差值形成的绝对值序列为非降序列

思路:先从小到大排序

最大的放在最后,最小的放在倒数第二位,第二大的放在倒数第三位,第二小的放在倒数第四位...

注意奇数特判

https://www.luogu.com.cn/record/32752274

C.数学

给定一个序列

你在第T秒可以给任意多个元素加上2^(T-1)

现在问你至少要到多少秒结束,才可以使得该序列成为非降序列

思路:显然你让它最后的值尽可能的小,并且2的P次方之和组合能构成1-2^(P+1)-1中所有取值可能,所以一旦你遇到一个元素比前者小,那么你就直接把它变得与前这相同即可

统计出现过最大差值它的最左位是几即可

https://www.luogu.com.cn/record/32752240

D.搜索,异或

给定一个树,你现在要给边权值,使得任意两个子节点形成的简单路径的异或和为0

求你给权值的种类最小是几,最大是几

思路:

首先它给的是树,任取一个节点建树(不一定是二叉树)

最小的无非是1或3

如果是任意叶节点之间他们形成的路径都是偶数条边,那么你赋同一个值即可,而存在单数条边,那么至少要用3个数,至于为什么(你可以考虑压缩路径化成链,链上边数为奇则要3个数)

而建树是随便取点的,故所有子树的叶节点深度奇偶性相同,才能为1

最大反过来想

假设所有边均可以给个数,再看看哪些边不成立

比如父节点只连接了两个单独的子节点,那么这两条边它们必须一样,这就少了一条边

void dfs(int cur,int fa,int depth)
{	
	if(node[cur].size()==1)
	{
	    if(depth&1)ji=1;
	    else ou=1;
	    ans-=vis[node[cur][0]];
	    vis[node[cur][0]]=1;
	}
	for(int i=0;i<node[cur].size();i++)
	{
	    if(node[cur][i]!=fa)dfs(node[cur][i],cur,depth+1);
	}
}

注意

ans-=vis[node[cur][0]];
vis[node[cur][0]]=1;

不能写成

ans-=vis[fa];
vis[fa]=1;

因为你是随缘建树的,父节点本身可能就是叶节点,所以要格外注意

https://www.luogu.com.cn/record/32754469

posted @ 2020-04-13 12:40  et3_tsy  阅读(124)  评论(0编辑  收藏  举报