Bzoj4763 雪辉
Submit: 151 Solved: 80
Description
Input
Output
Sample Input
0 0 1 0 0 2 2 0 0 0
2 3
1 2
4 5
3 4
7 8
6 7
5 6
9 10
8 9
4
1 7
3 3
1 1
9 3
Sample Output
HINT
Source
By nzhtl1477
树 树分块 bitset
询问区间mex,理论上桶是必须要开的。这题强制在线不能树上莫队,那就只能用bitset即时维护了。
直接爬树链显然不可取,我们可以考虑树分块。
统计一条链(x,y)的答案时,拆成(x,LCA)和(y,LCA)分别处理,先向上跳到当前点所在块的中心,然后整块往上跳,再跳完零碎的部分。
因为我们要查询的是链的信息,和区域无关,所以分块应该按照深度分而不是子树大小。
stl的bitset不支持询问mex,所以要手写bitset
博主码代码的时候出现了很多细节上的问题,导致复杂度不稳定,无情被卡。
这是一个悲伤的故事,这个故事告诉我们永远不要迷之自信地认为自己的诡异写法能艹过正解。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define UL long long 7 using namespace std; 8 const int mxn=110010; 9 const UL ful=0xFFFFFFFFFFFFFFFF; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();} 14 return x*f; 15 } 16 void write(int x){ 17 if(x>9)write(x/10); 18 putchar('0'+x%10); 19 return; 20 } 21 struct edge{ 22 int v,nxt; 23 }e[mxn<<1]; 24 int hd[mxn],mct=0; 25 void add_edge(int u,int v){ 26 e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return; 27 } 28 // 29 int num[65537]; 30 struct BIT{ 31 UL x[471]; 32 inline void clear(){memset(x,0,sizeof x);return;} 33 void insert(int a){ 34 int pos=a/64+1; 35 x[pos]|=1LL<<(a%64); 36 return; 37 } 38 void operator |= (const BIT &b){ 39 for(register int i=1;i<470;i++)x[i]|=b.x[i]; 40 return; 41 } 42 int mex(){ 43 for(int i=1;i<470;i++){ 44 if(x[i]!=ful){ 45 int res=0; 46 UL tmp=x[i]; 47 while(tmp&1){ 48 res++; 49 tmp>>=1; 50 } 51 return res+(i-1)*64; 52 } 53 } 54 return 469*64-1; 55 } 56 int calc(){ 57 int cnt=0; 58 for(int i=1;i<470;i++){ 59 if(!x[i])continue; 60 if(x[i]==ful)cnt+=64; 61 else{ 62 UL tmp=x[i]; 63 cnt+=num[(tmp&65535)]+num[(tmp>>16)&65535]; 64 tmp>>=32; 65 cnt+=num[(tmp&65535)]+num[(tmp>>16)&65535]; 66 } 67 } 68 return cnt; 69 } 70 }bt[320][320],res; 71 int block=0; 72 int dep[mxn],mx[mxn],bct=0; 73 int Cid[mxn],C[mxn],Cfa[mxn]; 74 int fa[mxn][19]; 75 void DFS(int u,int ff){ 76 mx[u]=0;dep[u]=dep[ff]+1; 77 for(int i=1;i<=17;i++)fa[u][i]=fa[fa[u][i-1]][i-1]; 78 for(int i=hd[u];i;i=e[i].nxt){ 79 int v=e[i].v;if(v==ff)continue; 80 fa[v][0]=u; 81 DFS(v,u); 82 mx[u]=max(mx[u],mx[v]+1); 83 } 84 if(mx[u]>=block || u==1){ 85 mx[u]=0; 86 bct++; Cid[u]=bct; C[bct]=u; Cfa[bct]=0; 87 } 88 return; 89 } 90 int LCA(int x,int y){ 91 if(dep[x]<dep[y])swap(x,y); 92 for(int i=17;i>=0;i--)if(dep[fa[x][i]]>=dep[y])x=fa[x][i]; 93 if(x==y)return x; 94 for(int i=17;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; 95 return fa[x][0]; 96 } 97 int n,Q,F; 98 int lastans=0; 99 int w[mxn]; 100 void Build(){ 101 block=sqrt(n+0.5); 102 DFS(1,0); 103 for(int i=1;i<=bct;i++){ 104 int u=C[i]; 105 res.clear(); 106 res.insert(w[u]);u=fa[u][0]; 107 while(u){ 108 res.insert(w[u]); 109 // 110 if(Cid[u]){ 111 bt[i][Cid[u]]=res; 112 if(!Cfa[i])Cfa[i]=u; 113 } 114 // 115 u=fa[u][0]; 116 } 117 } 118 return; 119 } 120 void query(int x,int y){ 121 if(dep[x]<dep[y])swap(x,y); 122 if(dep[x]-dep[y]<=block){ 123 while(dep[x]>=dep[y]){ 124 res.insert(w[x]); 125 x=fa[x][0]; 126 } 127 return; 128 } 129 while(dep[x]>=dep[y] && !Cid[x]){ 130 res.insert(w[x]); 131 x=fa[x][0]; 132 } 133 int tmp=x; 134 while(dep[Cfa[Cid[tmp]]]>=dep[y]){ 135 tmp=Cfa[Cid[tmp]]; 136 } 137 if(tmp^x)res|=bt[Cid[x]][Cid[tmp]]; 138 x=tmp; 139 while(dep[x]>=dep[y]){ 140 res.insert(w[x]); 141 x=fa[x][0]; 142 } 143 return; 144 } 145 void solve(){ 146 int a=read(),x,y; 147 res.clear(); 148 while(a--){ 149 x=read();y=read(); 150 if(F){x^=lastans;y^=lastans;} 151 // 152 int tmp=LCA(x,y); 153 query(x,tmp);query(y,tmp); 154 // 155 } 156 int ans1=res.mex(); 157 int ans2=res.calc(); 158 // printf("%d %d\n",ans2,ans1); 159 write(ans2);putchar(' ');write(ans1);puts(""); 160 lastans=ans1+ans2;// 161 return; 162 } 163 int main(){ 164 // freopen("in.txt","r",stdin); 165 // freopen("out2.txt","w",stdout); 166 int i,j,u,v; 167 n=read();Q=read();F=read(); 168 for(i=1;i<=n;i++)w[i]=read(); 169 for(i=1;i<n;i++){ 170 u=read();v=read(); 171 add_edge(u,v); 172 add_edge(v,u); 173 } 174 for(i=1;i<=65535;i++){ 175 int tmp=i; 176 while(tmp){ 177 num[i]++; 178 tmp-=tmp&-tmp; 179 } 180 } 181 Build(); 182 while(Q--)solve(); 183 return 0; 184 }
转载于:https://www.cnblogs.com/SilverNebula/p/7122953.html
Bzoj4763 雪辉相关推荐
- [洛谷]CON1466 洛谷2017春节联欢赛 Hello Dingyou题解 Bzoj4763雪辉
题目来源:https://www.luogu.org/contest/show?tid=1466 创建时间:2017/3/13 18:33 镇楼图: 猜猜她是谁~ 解题思路: 春节居然也有 ...
- [bzoj4763]雪辉[bzoj4812][Ynoi2017]由乃打扑克
来自FallDream的博客,未经允许,请勿转载,谢谢. cut掉部分题面. 给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有 ...
- 「BZOJ4763」雪辉
「BZOJ4763」天野雪辉 题目大意:有一棵 \(n\) 个点的树,树上每一个点有权值 \(a_i \leq 30000\) ,每次询问给出若干路径,求出这些路径的并上面的不同颜色数与 \(mex\ ...
- [BZOJ 4763]雪辉
[BZOJ 4763] 雪辉 题意 给定一棵 \(n\) 个点的无根树, 点带权. \(q\) 次询问, 每次给定树上的若干路径, 求这些路径上的点共有多少种不同权值以及这些点的权值组成的集合的 \( ...
- 4763: 雪辉[点分治+可持久化分块]
4763: 雪辉 Time Limit: 39 Sec Memory Limit: 666 MB Submit: 85 Solved: 51 [Submit][Status][Discuss] D ...
- [BZOJ4763][P3603]雪辉[手写bitset+静态分块]
题意:给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有出现的非负整数,注意0要算 rand出 \(\sqrt n\)个点,把每 ...
- [题解] 洛谷 P3603 雪辉
模拟赛中遇到了这个题,当时我这个沙雕因为把一个\(y\)打成了\(x\)而爆零.回来重新写这道题,莫名其妙的拿了rank1... 我的解法与其他几位的题解有些不同我太蒻了.并没有选取所谓的关键点,而是 ...
- bzoj 4763: 雪辉
Description 给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有出现的非负整数,注意0要算 比如说集合是1,9,2,6 ...
- 倒计时 4 天!年度开发者盛会 Unite Shanghai 2019 全日程揭晓(附表)
技术沉淀,华丽蜕变.跨越十四个春秋,Unity 在不断迭代的过程中已成为全球知名的游戏开发引擎,于此,其不仅可以为游戏开发者.发行商们带来底层工具的支持,更能够帮助各类的创作者.艺术家们实现各行各业高 ...
最新文章
- [SDK文档]SDK简介
- 减少过敏反应的生活细节
- 事务内容postgresql pgbench
- 13.transform确保目标空间足够大
- 搞定ubuntu下环境变量的配置
- C++之delete常见错误总结
- 利用宏定义在编译阶段检查结构体大小的方法
- IE11浏览器一个窗口打开多个页面设置方法
- Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转......
- Python Web笔记之高性能网络编程
- SparkStreaming读取本地文件进行wordCount
- Linux 安装 OFFICE 2007
- oracle叶子节点函数,oracle tree计算叶子节点到根节点的乘积
- Directx11代码下载
- 系统提示 api-ms-win-crt-runtime-l1-1-0.dll文件丢失,解决方法。。。
- 【模电知识总结】MOS管
- 鼠标键盘与计算机无法连接,蓝牙鼠标/键盘同时提示已配对 但是永远无法连接上...
- linux上redis升级(将 Redis 3.0.7 升级到 5.0.0版本)
- 学术会议html模板,关于学术研讨会邀请函的模板
- bzoj 1226 学校食堂