【左偏树】[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 }

 

 

 

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-11 15:37
点赞 评论 收藏
分享
Twilight_m...:表格简历有点难绷。说说个人看法: 1.个人基本情况里好多无意义信息,什么婚姻状况、健康状况、兴趣爱好、户口所在地、身份证号码、邮政编码,不知道的以为你填什么申请表呢。 2.校内实践个人认为对找工作几乎没帮助,建议换成和测开有关的项目,实在没得写留着也行。 3.工作经历完全看不出来是干什么的,起码看着和计算机没啥关系,建议加强描述,写点你在工作期间的实际产出、解决了什么问题。 4.个人简述大而空,看着像AI生成,感觉问题最大。“Python,C,C++成为我打造高效稳定服务的得力工具”、“我渴望凭借自身技术知识与创新能力,推动人工智能技术的应用发展,助力社会实现智能化转型”有种小学作文的美感。而且你确定你个人简述里写的你都会嘛?你AI这块写的什么“深入研究”,发几篇顶会的硕博生都不一定敢这么写。而且你AI这块的能力和软测也完全无关啊。个人简述建议写你对哪些技术栈、哪些语言、哪些生产工具的掌握,写的有条理些,而且最好是和测开强相关的。
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务