2020 China Collegiate Programming Contest Changchun F - Strange Memory(dsu on tree + 位运算小技巧)
题目连接:
https://codeforces.com/gym/102832/problem/F
首先写这个题的时候要注意内存的问题
不要瞎几把define int long long
题解:
考虑枚举LCA结点的话,好像跟dsu on tree有点像。
但是对于每个结点来说,如过每个结点的子树中找两个点等于根节点的值时间复杂度为O(n2)O(n^2)O(n2)的话,显然是不行的。
我们知道一个式子
如果a^b=c
那么b^c=a
那么这样的话,我们用一个cnt数组来记录一下 (假设这个lca结点只有两颗子树)lca结点和其中一颗树的所有结点的异或值出现的次数不就行了吗,我们遍历另一颗子树就可以O(1)知道另一颗子树是否有结点跟他异或等于根节点的结点了!。
但是这样就完了吗?
题目好像是让求,如果两个结点值异或值等于lca结点的值,那么就把 两个结点编号的异或值加到答案里。
cao
这样的话 怎么做啊?
难道对于每个cnt开一个vector,把等于某个值的(结点与lca结点的异或值)的结点编号给push进去。
每次查询到相同的然后遍历一波vector计算?
也不行,会被卡!
然后就从往上发现了一个很不错的优化方法。
我们计算异或值,可以按位来计算啊。
cnt[val][i][0∣1]cnt[val][i][0|1]cnt[val][i][0∣1] 代表 把等于某个值的(结点与lca结点的异或值)的结点编号x
x作为二进制的第i为是1还是0,如果是0,那么cnt[val][i][0]++cnt[val][i][0]++cnt[val][i][0]++ ,如果是1,那么cnt[val][i][1]++cnt[val][i][1]++cnt[val][i][1]++
这样处理的话时间复杂度会减少不少。
到时候计算的话只需要加上
感觉还是看代码理解容易些!
1ll*cnt[val^a[x]][i][!((x>>i)&1)]*bit[i];
//val^a[x]也就是代表前面b^c
//在第i位有多少个与他相反 的个数 因为异或运算
//bit为2^i
#include <bits/stdc++.h>using namespace std;
//#define int long long
const int maxn=1e5+10;int a[maxn];
vector<int> edge[maxn];//int fa[maxn];
int son[maxn],sz[maxn];
long long ans;int mp[1500010][21][2];
int bit[25];
void dfs(int x,int fa){sz[x]=1;for(auto i:edge[x]){if(i==fa) continue;dfs(i,x);sz[x]+=sz[i];if(sz[i]>sz[son[x]]) son[x]=i;}
}
int flag;void cont(int x,int fa,int val){for(int i=0;i<=20;i++){mp[a[x]][i][(x>>i)&1]+=val;}for(auto i:edge[x]){if(i==fa||i==flag) continue;cont(i,x,val);}
}void fun(int x,int fa,int val){for(int i=0;i<=20;i++){ans+=1ll*mp[val^a[x]][i][!((x>>i)&1)]*bit[i];}for(auto i:edge[x]){if(i==fa||i==flag) continue;fun(i,x,val);}
}void dsu(int x,int fa,bool keep){for(auto i:edge[x]){if(i==fa||i==son[x]) continue;dsu(i,x,false);}if(son[x]){dsu(son[x],x,true);flag=son[x];}for(auto i:edge[x]){if(i==fa||i==son[x]) continue;fun(i,x,a[x]);cont(i,x,1);}for(int i=0;i<=20;i++){mp[a[x]][i][(x>>i)&1]++;}flag=0;if(!keep){cont(x,fa,-1);}}
signed main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int n;cin>>n;bit[0]=1;for(int i=1;i<25;i++){bit[i]=bit[i-1]*2;}for(int i=1;i<=n;i++) cin>>a[i];for(int i=0;i<n-1;i++){int x,y;cin>>x>>y;edge[x].push_back(y);edge[y].push_back(x);}dfs(1,0);dsu(1,0,false);cout<<ans<<endl;return 0;
}
2020 China Collegiate Programming Contest Changchun F - Strange Memory(dsu on tree + 位运算小技巧)相关推荐
- acm -(并查集、启发式合并、gcd、枚举因子)2020 China Collegiate Programming Contest Changchun Onsite K. Ragdoll
传送门 本题考虑直接对每个iii求出所有满足ij=gcd(i,j)i^j=gcd(i,j)ij=gcd(i,j)的jjj,然后存在ggg数组中,对于查询修改操作维护一个并查集即可,合并的时候采用启发式 ...
- 2020 CCPC Changchun F :Strange Memory dsu on tree
传送门 分析 一开始读错题了,以为是个算贡献的水题... 树上静态统计,考虑dfsuontreedfsu \ on \ treedfsu on tree,我们去维护每一个值对应每一个二进制位出现了多少 ...
- 2020 China Collegiate Programming Contest Qinhuangdao Site 补题部分
已经补AEFGK E. Exam Results 枚举+二分+动态开点权值线段树O(nlogN)O(nlogN)O(nlogN) 智商太低,想不到什么贪心只能暴力数据结构维护 对于所有学生的最高成绩只 ...
- 2020 China Collegiate Programming Contest, Weihai B Labyrinth
写在前面: 这题赛时就过了二十多个人感觉还是榜歪了,完全没有到金牌题的水平,算是一道纯思维题吧,只需要简单的bfs,而且赛中也有一些铜牌区的队伍能过,所以还是要敢于开题,说不定就能写呢 题目链接 La ...
- 2020 China Collegiate Programming Contest Weihai Site补题部分
A. Golden Spirit 签到题,首先把所有老人带到对岸,然后在对休息讨论一下即可. #define IO ios::sync_with_stdio(false);cin.tie();cout ...
- acm-(辗转相除法、丢番图方程)2020 China Collegiate Programming Contest Qinhuangdao Site I. Interstellar Hunter
传送门 本题其实就是给定若干个整数向量(x1,y1),(x2,y2),...,(xn,yn)(x_1,y_1),(x_2,y_2),...,(x_n,y_n)(x1,y1),(x2,y2),. ...
- 2020 China Collegiate Programming Contest Weihai Site H.Message Bomb
H.Message Bomb 题目链接-H.Message Bomb 题目大意 输入sss行数据, 如果t=1t=1t=1,则表示第x个学生加入了第yyy个组.可以肯定的是,这个学生以前不在这个小组里 ...
- 2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program
2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program 题目链接 The kingdom of Z ...
- 2016 China Collegiate Programming Contest Final
2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...
最新文章
- List集合去重的一种方法
- Jquery背景图片的预加载
- 【Android 逆向】应用安装目录 ( Android 应用的默认安装目录 | 查找 Android 应用的安装目录 | 查询当前正在运行的应用包名 | 根据包名查询应用安装路径 )
- 【Android Protobuf 序列化】Protobuf 性能测试 ( fastjson 序列化与反序列化 | gson 序列化与反序列化 | 三种序列化与反序列化性能对比 )
- 怎么制作铁闸门_红茶拿铁
- 手机端适配rem计算方法
- python3.7.3 离线安装paramiko_python3和paramiko安装
- php开源qq群,QQ群免IDKEY加群PHP源码
- opencart配置United States Postal Service快递
- Java基础篇:一个堆栈类
- Java并发容器--ConcurrentLinkedQueue
- 解决办法:.No package ‘freetype2‘ found
- Web漏洞之CORS与JSONP跨域漏洞
- 关于支付宝口碑的界面问题
- C盘清理方法——基于spacesniffer软件和PatchCleaner软件
- 他们联手造了个抢票节”
- 浏览器劫持解决:解决浏览器的捆绑问题
- Android获取手机中外置内存卡、内置内存卡、手机内存路径
- ios avplayer播放完毕监听
- 计算机网络学习笔记(详尽版)