MarioYC

TJU 3755 - Graph and Queries

Apr 24th, 2012
430
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.88 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. #define MAXN 20001
  8. #define MAXM 60000
  9. #define MAXQ 460000
  10.  
  11. long long seed = 47;
  12.  
  13. long long my_rand(){
  14.     seed = (seed * 279470273) % 4294967291LL;
  15.     return seed;
  16. }
  17.  
  18. struct item{
  19.     int key;
  20.     long long prior;
  21.     item *l,*r;
  22.     int sons;
  23.    
  24.     item(){}
  25.    
  26.     item(int key) : key(key), l(NULL), r(NULL){
  27.         prior = my_rand();
  28.     }
  29.    
  30.     ~item(){
  31.         if(l) delete l;
  32.         if(r) delete r;
  33.     }
  34. };
  35.  
  36. item* T[MAXN];
  37. item* aux;
  38.  
  39. void fix(item* t){
  40.     if(!t) return;
  41.    
  42.     t->sons = (t->l ? t->l->sons + 1 : 0) +
  43.         (t->r ? t->r->sons + 1 : 0);
  44. }
  45.  
  46. void split(item* t, int key, item* &l, item* &r){
  47.     if(!t)
  48.         l = r = NULL;
  49.     else if(key < t->key)
  50.         split(t->l,key,l,t->l), r = t;
  51.     else
  52.         split(t->r,key,t->r,r), l = t;
  53.    
  54.     fix(t);
  55. }
  56.  
  57. void insert(item* &t, item* it){
  58.     if(!t)
  59.         t = it;
  60.     else if(it->prior > t->prior)
  61.         split(t, it->key, it->l, it->r), t = it;
  62.     else
  63.         insert(it->key < t->key ? t->l : t->r, it);
  64.    
  65.     fix(t);
  66. }
  67.  
  68. void merge(item* &t, item* l, item* r){
  69.     if(!l || !r)
  70.         t = l ? l : r;
  71.     else if(l->prior > r->prior)
  72.         merge(l->r, l->r, r), t = l;
  73.     else
  74.         merge(r->l, l, r->l), t = r;
  75.    
  76.     fix(t);
  77. }
  78.  
  79. void erase(item* &t, int key){
  80.     if(t->key == key)
  81.         merge(t, t->l, t->r);
  82.     else
  83.         erase(key < t->key ? t->l : t->r, key);
  84.    
  85.     fix(t);
  86. }
  87.  
  88. item* unite(item* l, item* r){
  89.     if(!l || !r) return l ? l : r;
  90.     if(l->prior < r->prior) swap (l, r);
  91.    
  92.     item *lt,*rt;
  93.    
  94.     split(r, l->key, lt, rt);
  95.     l->l = unite(l->l, lt);
  96.     l->r = unite(l->r, rt);
  97.    
  98.     return l;
  99. }
  100.  
  101. int get_Kth(item* &t, int K){
  102.     int x = (t->l == NULL? 0 : 1 + t->l->sons);
  103.    
  104.     if(K == x) return t->key;
  105.     if(K < x) return get_Kth(t->l,K);
  106.     return get_Kth(t->r,K - x - 1);
  107. }
  108.  
  109. int w[MAXN],parent[MAXN],sz[MAXN];
  110. int u[MAXM],v[MAXM];
  111. bool ins[MAXM];
  112.  
  113. int Find(int x){
  114.     if(parent[x] != x) parent[x] = Find(parent[x]);
  115.     return parent[x];
  116. }
  117.  
  118. void Union(int x, int y){
  119.     x = Find(x); y = Find(y);
  120.    
  121.     if(x != y){
  122.         parent[x] = y;
  123.         sz[y] += sz[x];
  124.     }
  125. }
  126.  
  127. int Q,type[MAXQ],param1[MAXQ],param2[MAXQ];
  128.  
  129. int main(){
  130.     int tc = 1,N,M;
  131.     char s[2];
  132.    
  133.     while(true){
  134.         scanf("%d %d",&N,&M);
  135.         if(N == 0) break;
  136.        
  137.         for(int i = 1;i <= N;++i)
  138.             scanf("%d",&w[i]);
  139.        
  140.         memset(ins,true,sizeof ins);
  141.        
  142.         for(int i = 1;i <= M;++i)
  143.             scanf("%d %d",&u[i],&v[i]);
  144.        
  145.         int cont = 0;
  146.         Q = 0;
  147.        
  148.         while(true){
  149.             scanf("%s",s);
  150.            
  151.             if(s[0] == 'E') break;
  152.            
  153.             if(s[0] == 'D'){
  154.                 type[Q] = 0;
  155.                 scanf("%d",&param1[Q]);
  156.                 ins[ param1[Q] ] = false;
  157.             }
  158.            
  159.             if(s[0] == 'Q'){
  160.                 type[Q] = 1;
  161.                 scanf("%d %d",&param1[Q],&param2[Q]);
  162.                 ++cont;
  163.             }
  164.            
  165.             if(s[0] == 'C'){
  166.                 type[Q] = 2;
  167.                 scanf("%d %d",&param1[Q],&param2[Q]);
  168.                 swap(param2[Q],w[ param1[Q] ]);
  169.             }
  170.            
  171.             ++Q;
  172.         }
  173.        
  174.         for(int i = 1;i <= N;++i){
  175.             parent[i] = i;
  176.             sz[i] = 1;
  177.         }
  178.        
  179.         for(int i = 1;i <= M;++i)
  180.             if(ins[i]) Union(u[i],v[i]);
  181.        
  182.         for(int i = 1;i <= N;++i)
  183.             if(parent[i] == i)
  184.                 T[i] = new item(10000000);
  185.        
  186.         for(int i = 1;i <= N;++i)
  187.             insert(T[ Find(i) ],new item(w[i]));
  188.        
  189.         long long sum = 0;
  190.        
  191.         for(int q = Q - 1;q >= 0;--q){
  192.             if(type[q] == 0){
  193.                 int e = param1[q];
  194.                
  195.                 u[e] = Find(u[e]); v[e] = Find(v[e]);
  196.                
  197.                 if(u[e] != v[e]){
  198.                     Union(u[e],v[e]);
  199.                     aux = unite(T[ u[e] ],T[ v[e] ]);
  200.                     T[ v[e] ] = aux;
  201.                 }
  202.             }
  203.            
  204.             if(type[q] == 1){
  205.                 int r = Find(param1[q]);
  206.                
  207.                 if(param2[q] <= sz[r])
  208.                     sum += get_Kth(T[r],sz[r] - param2[q]);
  209.             }
  210.            
  211.             if(type[q] == 2){
  212.                 erase(T[ Find(param1[q]) ],w[ param1[q] ]);
  213.                 insert(T[ Find(param1[q]) ],new item(param2[q]));
  214.                 w[ param1[q] ] = param2[q];
  215.             }
  216.         }
  217.        
  218.         for(int i = 1;i <= N;++i)
  219.             if(parent[i] == i)
  220.                 delete T[i];
  221.        
  222.         printf("Case %d: %.6f\n",tc++,(double)sum / cont);
  223.     }
  224.    
  225.     return 0;
  226. }
Advertisement
Add Comment
Please, Sign In to add comment