【左偏树】[LuoguP1456] Monkey King

多...多组数据...

awsl

死命的MLE,原来是忘记清空数组了....

左偏树模板?

对于每一个操作,我们把两个节点$x,y$的祖先$fx,fy$找到,然后把他们的左右儿子分别合并

最后把$v[fx],v[fy]$分别>>1再合并回去就好了

 1 // luogu-judger-enable-o2
 2 #include<bits/stdc++.h>
 3 #define writeln(x)  write(x),puts("")
 4 #define writep(x)   write(x),putchar(' ')
 5 using namespace std;
 6 inline int read(){
 7     int ans=0,f=1;char chr=getchar();
 8     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
 9     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
10     return ans*f;
11 }void write(int x){
12     if(x<0) putchar('-'),x=-x;
13     if(x>9) write(x/10);
14     putchar(x%10+'0');
15 }const long M=1e5+5;
16 int son[M][2],dis[M],v[M],rt[M],n,m;
17 int Find(int x){if(rt[x]==x)return x;return rt[x]=Find(rt[x]);}
18 #define ls son[x][0]
19 #define rs son[x][1]
20 int Merge(int x,int y){
21     if(!x||!y) return x+y;
22     if(v[x]<v[y]) swap(x,y);
23     rs=Merge(rs,y);
24     if(dis[ls]<dis[rs]) swap(ls,rs);
25     rt[ls]=rt[rs]=rt[x]=x;
26     dis[x]=dis[rs]+1;
27     return x;
28 }
29 void Pop(int x){
30     v[x]=-1;rt[ls]=ls,rt[rs]=rs;
31     rt[x]=Merge(ls,rs);
32 }
33 signed main(){
34     while(~scanf("%d",&n)){
35         memset(son,0,sizeof(son));
36         memset(v,0,sizeof(v));
37         memset(dis,0,sizeof(dis));
38         dis[0]=-1;
39         for(int i=1;i<=n;i++)    rt[i]=i,v[i]=read();
40         m=read();
41         while(m--){
42             int x=read(),y=read();
43             int fx=Find(x),fy=Find(y);
44             if(fx==fy) puts("-1");
45             else{
46                 v[fx]>>=1,v[fy]>>=1;
47                 int tx=Merge(son[fx][0],son[fx][1]);
48                 rt[son[fx][0]]=rt[son[fx][1]]=tx;
49                 son[fx][0]=son[fx][1]=dis[fx]=0;
50                 rt[fx]=fx;
51                 int ty=Merge(son[fy][0],son[fy][1]);
52                 rt[son[fy][0]]=rt[son[fy][1]]=ty;
53                 son[fy][0]=son[fy][1]=dis[fy]=0;
54                 rt[fy]=fy;
55                 int root=Merge(tx,ty);
56                 root=Merge(fx,root);
57                 root=Merge(fy,root);
58                 cout<<v[root]<<endl;
59             }
60         }
61     }
62     return 0;
63 }

 

 

 

全部评论

相关推荐

10-15 10:57
已编辑
武昌理工学院 FPGA工程师
狠赚笔第一人:老哥学院本没实习还想拿13k学Java狠赚笔呢
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务