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;
因为你是随缘建树的,父节点本身可能就是叶节点,所以要格外注意