洛谷 P2713 罗马游戏(左偏树)
传送门
解题思路
就是个板子。
注意一下两点:
1.scanf读入int后接着读char会把回车读进去,处理方法: %c前加个空格,即scanf(" %c",&c);
2.i有可能等于j,所以要判断一下,否则第四个点惨痛MLE。
AC代码
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstdio> 5 #include<cstring> 6 using namespace std; 7 const int maxn=1000005; 8 int n,m,a[maxn],fa[maxn],vis[maxn]; 9 char c; 10 struct node{ 11 int ls,rs,dis; 12 }t[maxn]; 13 int find(int x){ 14 return fa[x]==x?x:fa[x]=find(fa[x]); 15 } 16 void pushup(int x){ 17 if(t[t[x].rs].dis>t[t[x].ls].dis) swap(t[x].rs,t[x].ls); 18 t[x].dis=t[t[x].rs].dis+1; 19 } 20 int merge(int x,int y){ 21 if(!x||!y) return x|y; 22 if(a[x]>a[y]) swap(x,y); 23 t[x].rs=merge(t[x].rs,y); 24 fa[t[x].rs]=x; 25 pushup(x); 26 return x; 27 } 28 void goout(int x){ 29 fa[t[x].ls]=t[x].ls; 30 fa[t[x].rs]=t[x].rs; 31 int newtop=merge(t[x].ls,t[x].rs); 32 fa[x]=newtop; 33 } 34 int main() 35 { 36 cin>>n; 37 for(int i=1;i<=n;i++) fa[i]=i; 38 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 39 scanf("%d",&m); 40 for(int i=1;i<=m;i++){ 41 scanf(" %c",&c); 42 if(c=='M'){ 43 int x,y; 44 scanf("%d%d",&x,&y); 45 if(vis[x]||vis[y]) continue; 46 x=find(x); 47 y=find(y); 48 if(x==y) continue; 49 merge(x,y); 50 }else{ 51 int x; 52 scanf("%d",&x); 53 if(vis[x]){ 54 printf("0\n"); 55 }else{ 56 x=find(x); 57 printf("%d\n",a[x]); 58 goout(x); 59 vis[x]=1; 60 } 61 } 62 } 63 return 0; 64 }