zoj 2112 Dynamic Rankings

原题链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1112

  1 #include<cstdio>  
  2 #include<cstdlib>  
  3 #include<cstring>  
  4 #include<algorithm>  
  5 #define lc root<<1  
  6 #define rc root<<1|1  
  7 #define INF 0x3f3f3f3f  
  8 const int Max_N = 50010;  
  9 struct SBT{  
 10     int key, size, cnt;  
 11     SBT *ch[2];  
 12     inline void push_up(){  
 13         size = ch[0]->size + ch[1]->size + cnt;  
 14     }  
 15     int cmp(int v) const{  
 16         if (v == key) return -1;  
 17         return v > key;  
 18     }  
 19 }*null, stack[Max_N * 18], *ptr[Max_N << 2];  
 20 int sz = 0, sum = 0, arr[Max_N];  
 21 void init(){  
 22     null = &stack[sz++];  
 23     null->key = null->size = null->cnt = 0;  
 24 }  
 25 void rotate(SBT* &x, int d){  
 26     SBT *k = x->ch[!d];  
 27     x->ch[!d] = k->ch[d];  
 28     k->ch[d] = x;  
 29     k->size = x->size;  
 30     x->push_up();  
 31     x = k;  
 32 }  
 33 void Maintain(SBT* &x, int d){  
 34     if (x->ch[d] == null) return;  
 35     if (x->ch[d]->ch[d]->size > x->ch[!d]->size){  
 36         rotate(x, !d);  
 37     } else if (x->ch[d]->ch[!d]->size > x->ch[!d]->size){  
 38         rotate(x->ch[d], d), rotate(x, !d);  
 39     } else {  
 40         return;  
 41     }  
 42     Maintain(x, 0), Maintain(x, 1);  
 43 }  
 44 void insert(SBT* &x, int key){  
 45     if (x == null){  
 46         x = &stack[sz++];  
 47         x->ch[0] = x->ch[1] = null;  
 48         x->key = key, x->size = x->cnt = 1;  
 49     } else {  
 50         int d = x->cmp(key);  
 51         x->size++;  
 52         if (-1 == d){  
 53             x->cnt++;  
 54             return;  
 55         }  
 56         insert(x->ch[d], key);  
 57         x->push_up();  
 58         Maintain(x, d);  
 59     }  
 60 }  
 61 void del(SBT* &x, int key){  
 62     if (x == null) return;  
 63     int d = x->cmp(key);  
 64     x->size--;  
 65     if (-1 == d){  
 66         if (x->cnt > 1){  
 67             x->cnt--;  
 68         } else if (x->ch[0] == null || x->ch[1] == null){  
 69             x = x->ch[0] != null ? x->ch[0] : x->ch[1];  
 70         } else {  
 71             SBT *ret = x->ch[1];  
 72             for (; ret->ch[0] != null; ret = ret->ch[0]);  
 73             del(x->ch[1], x->key = ret->key);  
 74         }  
 75     } else {  
 76         del(x->ch[d], key);  
 77     }  
 78     if (x != null) x->push_up();  
 79 }  
 80 int sbt_rank(SBT *x, int key){  
 81     int t, cur;  
 82     for (t = cur = 0; x != null;){  
 83         t = x->ch[0]->size;  
 84         if (key < x->key) x = x->ch[0];  
 85         else if (key >= x->key) cur += x->cnt + t, x = x->ch[1];  
 86     }  
 87     return cur;  
 88 }  
 89 void seg_built(int root, int l, int r){  
 90     for (int i = l; i <= r; i++) insert(ptr[root], arr[i]);  
 91     if (l == r) return;  
 92     int mid = (l + r) >> 1;  
 93     seg_built(lc, l, mid);  
 94     seg_built(rc, mid + 1, r);  
 95 }  
 96 void seg_query(int root, int l, int r, int x, int y, int val){  
 97     if (x > r || y < l) return;  
 98     if (x <= l && y >= r){  
 99         sum += sbt_rank(ptr[root], val);  
100         return;  
101     }  
102     int mid = (l + r) >> 1;  
103     seg_query(lc, l, mid, x, y, val);  
104     seg_query(rc, mid + 1, r, x, y, val);  
105 }  
106 void seg_del(int root, int l, int r, int pos, int val){  
107     if (pos > r || pos < l) return;  
108     del(ptr[root], val);  
109     if (l == r) return;  
110     int mid = (l + r) >> 1;  
111     seg_del(lc, l, mid, pos, val);  
112     seg_del(rc, mid + 1, r, pos, val);  
113 }  
114 void seg_insert(int root, int l, int r, int pos, int val) {  
115     if (pos > r || pos < l) return;  
116     insert(ptr[root], val);  
117     if (l == r) return;  
118     int mid = (l + r) >> 1;  
119     seg_insert(lc, l, mid, pos, val);  
120     seg_insert(rc, mid + 1, r, pos, val);  
121 }  
122 void gogo(int n, int a, int b, int k){  
123     int l = 0, r = INF;  
124     while (l < r){  
125         sum = 0;  
126         int mid = (l + r) >> 1;  
127         seg_query(1, 1, n, a, b, mid);  
128         if (sum < k) l = mid + 1;  
129         else r = mid;  
130     }  
131     printf("%d
", l);  
132 }  
133 int main(){  
134 #ifdef LOCAL  
135     freopen("in.txt", "r", stdin);  
136     freopen("out.txt", "w+", stdout);  
137 #endif  
138     char ch;  
139     int t, n, m, a, b, k;  
140     scanf("%d", &t);  
141     while (t--){  
142         sz = 0, init();  
143         scanf("%d %d", &n, &m);  
144         for (int i = 1; i <= n; i++) scanf("%d", &arr[i]);  
145         std::fill(ptr, ptr + (n << 2), null);  
146         seg_built(1, 1, n);  
147         while (m--){  
148             getchar();  
149             scanf("%c", &ch);  
150             if (ch == 'Q'){  
151                 scanf("%d %d %d", &a, &b, &k);  
152                 gogo(n, a, b, k);  
153             } else {  
154                 scanf("%d %d", &a, &b);  
155                 seg_del(1, 1, n, a, arr[a]);  
156                 seg_insert(1, 1, n, a, arr[a] = b);  
157             }  
158         }  
159     }  
160     return 0;  
161 }
View Code
By: GadyPu 博客地址:http://www.cnblogs.com/GadyPu/ 转载请说明
原文地址:https://www.cnblogs.com/GadyPu/p/4451842.html