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\n", 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

 

你可能感兴趣的:(dynamic)