2018 ICPC南京网络赛 Set(字典树 + 合并 + lazy更新)
Posted songorz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 ICPC南京网络赛 Set(字典树 + 合并 + lazy更新)相关的知识,希望对你有一定的参考价值。
题解:n个集合,你要进行m个操作。总共有3种操作。第一种,合并两个集合x和y。第二张,把特定的集合里面所有的数字加一。第三种,询问在某个集合里面,对于所有数字对2的k次方取模后,有多少个数字等于x。
思路:我们可以对于每一个节点保存一个lazy标记,这个标记类似于线段树中的lazy标记。每次整个集合增加的时候,只改变lazy标记,然后在下一次访问这个节点的时候,再去把这个标记push_down。而这个push_down的方式就是按照之前说的那样,根据lazy的奇偶来判断是否应该交换儿子和额外进位。对于每一个查询操作,我们直接把放到字典树中,确定一个位置,输出对应节点的size即可。具体操作的时候还要注意,一定要把每一个插入的数字固定插入长度设置为30,因为数字的高位即使为0也是需要保存的。
参考代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=1e6+10; const int depth=31; struct Trie #define ls T[x].ch[0] #define rs T[x].ch[1] int tot; struct Node int siz,ch[2],tag; T[maxn<<5]; void Init()tot=0; int NewNode()memset(&T[++tot],0,sizeof(T[0]));return tot; void pushdown(int x) int lz=T[x].tag; if(lz&1)swap(ls,rs);T[ls].tag++; T[ls].tag+=lz/2; T[rs].tag+=lz/2; T[x].tag=0; void Insert(int &rt,int x) int o=rt?rt:rt=NewNode(),c; for(int i=0;i<depth;++i) c=x&1; x>>=1; T[o].siz++; if(T[o].tag) pushdown(o); if(!T[o].ch[c]) T[o].ch[c]=NewNode(); o=T[o].ch[c]; int query(int rt,int x,int y) int o=rt; for(int k=0;k<y;++k) if(T[o].tag) pushdown(o); o=T[o].ch[x&1];x>>=1;if(!o) break; return T[o].siz; void Merge(int x,int y) T[x].siz+=T[y].siz; if(T[x].tag) pushdown(x); if(T[y].tag) pushdown(y); for(int i=0;i<2;++i) if(T[x].ch[i]&&T[y].ch[i]) Merge(T[x].ch[i],T[y].ch[i]); if(!T[x].ch[i]&&T[y].ch[i]) T[x].ch[i]=T[y].ch[i]; trie; int n,m,rt[maxn],f[maxn]; int find(int x) return f[x]==x?x:f[x]=find(f[x]); int main() while(~scanf("%d",&n)) scanf("%d",&m); memset(rt,0,sizeof rt); trie.Init(); for(int i=1;i<=n;i++) f[i]=i; int x;scanf("%d",&x); trie.Insert(rt[i],x); while(m--) int op,x,y,z; scanf("%d",&op); if(op==1) scanf("%d%d",&x,&y); x=find(x); y=find(y); if(x!=y) trie.Merge(rt[x],rt[y]),f[y]=x; if(op==2) scanf("%d",&x); trie.T[rt[find(x)]].tag++; if(op==3) scanf("%d%d%d",&x,&y,&z); x=find(x); printf("%d\\n",trie.query(rt[x],z,y)); return 0;
以上是关于2018 ICPC南京网络赛 Set(字典树 + 合并 + lazy更新)的主要内容,如果未能解决你的问题,请参考以下文章
2018ICPC南京网络赛 AAn Olympian Math Problem(数论题)
2019南京ICPC(重现赛) F - Paper Grading