Graph and Queries
第一道Treap,对着白书敲的=_=||
1 #include <bits/stdc++.h> 2 using namespace std; 3 //15:15--16:00 4 struct Node{ 5 Node *ch[2]; //左右子树 6 int r; //随机优先级 7 int v; //值 8 int s; //节点总数 9 Node(int v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1; } 10 bool operator <(const Node &a)const { 11 return r<a.r; 12 } 13 int cmp(int x)const { 14 if(x==v) return -1; 15 return x<v ? 0:1; 16 } 17 18 void maintain(){ 19 s=1; 20 if(ch[0]!=NULL) s+=ch[0]->s; 21 if(ch[1]!=NULL) s+=ch[1]->s; 22 } 23 }; 24 25 void rotate(Node* &o,int d){ //0左旋,1右旋 26 Node *k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o; 27 o->maintain();k->maintain();o=k; 28 } 29 30 void insert(Node* &o,int x){ 31 if(o==NULL) o=new Node(x); 32 else { 33 int d=(x<o->v?0:1); //不用cmp函数,因为可能有相同节点 34 insert(o->ch[d],x); 35 if(o->ch[d]->r>o->r) rotate(o,d^1); 36 } 37 o->maintain(); 38 } 39 40 void remove(Node* &o,int x){ 41 int d=o->cmp(x); 42 if(d==-1){ 43 Node* u=o; 44 if(o->ch[0]!=NULL&&o->ch[1]!=NULL){ 45 int d2=(o->ch[0]->r>o->ch[1]->r?1:0); 46 rotate(o,d2);remove(o->ch[d2],x); 47 }else { 48 if(o->ch[0]==NULL) o=o->ch[1];else o=o->ch[0]; 49 delete u; // 50 } 51 }else 52 remove(o->ch[d],x); 53 if(o!=NULL) o->maintain(); 54 } 55 56 const int maxc=500000+10; 57 58 struct Command 59 { 60 char type; 61 int x,p; //根据type,p代表k或者v 62 }command[maxc]; 63 64 const int maxn=20000+10; 65 const int maxm=60000+10; 66 67 int n,m,weight[maxn],from[maxm],to[maxm],removed[maxm]; 68 69 //并查集 70 int pa[maxn]; 71 int gf(int x){ 72 return x==pa[x]?x:pa[x]=gf(pa[x]); 73 } 74 75 //名次树 76 Node* root[maxn]; //Treap 77 int kth(Node* o,int k){ 78 if(o==NULL||k<=0||k>o->s) return 0; 79 int s=(o->ch[1]==NULL?0:o->ch[1]->s); 80 if(k==s+1) return o->v; 81 else if(k<=s) return kth(o->ch[1],k); 82 else return kth(o->ch[0],k-s-1); 83 } 84 85 void mergeto(Node* &a,Node* &b){ 86 if(a->ch[0]!=NULL) mergeto(a->ch[0],b); 87 if(a->ch[1]!=NULL) mergeto(a->ch[1],b); 88 insert(b,a->v); 89 delete a; 90 a=NULL; 91 } 92 93 void removetree(Node* &x){ 94 if(x->ch[0]!=NULL) removetree(x->ch[0]); 95 if(x->ch[1]!=NULL) removetree(x->ch[1]); 96 delete x; 97 x=NULL; 98 } 99 //主程序相关 100 void add_edge(int x){ 101 int u=gf(from[x]),v=gf(to[x]); 102 if(u!=v){ 103 if(root[u]->s<root[v]->s){ 104 pa[u]=v; 105 mergeto(root[u],root[v]); 106 }else { 107 pa[v]=u; 108 mergeto(root[v],root[u]); 109 } 110 } 111 } 112 113 int query_cnt; 114 long long query_tot; 115 void query(int x,int k){ 116 query_cnt++; 117 query_tot+=kth(root[gf(x)],k); 118 } 119 120 void change_weight(int x,int v){ 121 int u=gf(x); 122 remove(root[u],weight[x]); 123 insert(root[u],v); 124 weight[x]=v; 125 } 126 127 int main(){ 128 int kase=0; 129 while(scanf("%d%d",&n,&m)==2&&n){ 130 for(int i=1;i<=n;i++) scanf("%d",&weight[i]); 131 for(int i=1;i<=m;i++) scanf("%d%d",&from[i],&to[i]); 132 memset(removed,0,sizeof(removed)); 133 134 //读命令 135 int c=0; 136 for(;;){ 137 char type; 138 int x,p=0,v=0; 139 scanf(" %c",&type); 140 if(type=='E') break; 141 scanf("%d",&x); 142 if(type=='D') removed[x]=1; 143 if(type=='Q') scanf("%d",&p); 144 if(type=='C'){ 145 scanf("%d",&v); 146 p=weight[x]; 147 weight[x]=v; 148 } 149 command[c++]=(Command){type,x,p}; 150 } 151 152 //最终的图 153 for(int i=1;i<=n;i++){ 154 pa[i]=i; 155 if(root[i]!=NULL) removetree(root[i]); 156 root[i]=new Node(weight[i]); 157 } 158 159 for(int i=1;i<=m;i++) if(!removed[i]) add_edge(i); 160 161 //反向操作 162 query_tot=query_cnt=0; 163 for(int i=c-1;i>=0;i--){ 164 if(command[i].type=='D') add_edge(command[i].x); 165 if(command[i].type=='Q') query(command[i].x,command[i].p); 166 if(command[i].type=='C') change_weight(command[i].x,command[i].p); 167 } 168 printf("Case %d: %.6lf ",++kase,query_tot/(double)query_cnt); 169 } 170 return 0; 171 }