【题目大意】
给出一些数和一些操作。M:合并两个数所在的集合,如果有任意一个数被删除则忽略操作;K:删除某个数所在集合中最小的数。
【思路】
裸裸的,复习^ ^
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=1000000+500; 7 struct node 8 { 9 int key,dis,del; 10 int lson,rson,father; 11 }ltree[MAXN]; 12 int n,m; 13 14 int find(int a) 15 { 16 while (ltree[a].father!=a) a=ltree[a].father; 17 return a; 18 } 19 20 void build(int rt,int val) 21 { 22 ltree[rt].key=val; 23 ltree[rt].dis=(rt==0)?-1:0; 24 ltree[rt].del=0; 25 ltree[rt].lson=ltree[rt].rson=0; 26 ltree[rt].father=rt; 27 } 28 29 int merge(int x,int y) 30 { 31 if (x==0||y==0) return (x|y); 32 if (ltree[x].key>ltree[y].key) swap(x,y); 33 ltree[x].rson=merge(ltree[x].rson,y); 34 int &l=ltree[x].lson,&r=ltree[x].rson; 35 ltree[l].father=ltree[r].father=x; 36 if (ltree[l].dis<ltree[r].dis) swap(l,r); 37 if (r==0) ltree[x].dis=0; 38 else ltree[x].dis=ltree[r].dis+1; 39 return x; 40 } 41 42 void Del(int rt) 43 { 44 int l=ltree[rt].lson,r=ltree[rt].rson; 45 ltree[l].father=l; 46 ltree[r].father=r; 47 ltree[rt].dis=ltree[rt].lson=ltree[rt].rson=0; 48 ltree[rt].del=1; 49 merge(l,r); 50 } 51 52 void init() 53 { 54 scanf("%d",&n); 55 for (int i=1;i<=n;i++) 56 { 57 int score; 58 scanf("%d",&score); 59 build(i,score); 60 } 61 build(0,0); 62 } 63 64 void solve() 65 { 66 scanf("%d",&m); 67 for (int i=0;i<m;i++) 68 { 69 char op[1]; 70 scanf("%s",op); 71 if (op[0]==‘M‘) 72 { 73 int a,b; 74 scanf("%d%d",&a,&b); 75 if (!ltree[a].del&&!ltree[b].del) 76 { 77 int fa=find(a),fb=find(b); 78 if (fa!=fb) merge(fa,fb);//不要忘记要判断两者不在同一个集合中 79 } 80 } 81 if (op[0]==‘K‘) 82 { 83 int a; 84 scanf("%d",&a); 85 if (ltree[a].del) puts("0"); 86 else 87 { 88 int fa=find(a); 89 printf("%d\n",ltree[fa].key); 90 Del(fa); 91 } 92 } 93 } 94 } 95 96 int main() 97 { 98 init(); 99 solve(); 100 return 0; 101 }
时间: 2024-10-14 17:10:21