洛谷P2617 Dynamic Rankings

题意:带修区间第k大。

具体来说,就是带修主席树模板题。

解:唔...不离散化的话疯狂卡常都过不去,离散化就A了...虽然还是很慢。

把主席树换成树状数组套动态开点线段树即可。

  1 #include <algorithm>
  2 #include <cstdio>
  3 
  4 const int N = 100010, M = 45000010;
  5 
  6 struct Node {
  7     int f, x, y, z;
  8 }node[N];
  9 
 10 int a[N], now[N], rt[N], tot, n, p[N], tp, X[N << 1], temp;
 11 int sum[M], ls[M], rs[M];
 12 char str[3];
 13 bool vis[N];
 14 
 15 inline void read(int &x) {
 16     x = 0;
 17     char c = getchar();
 18     while(c < '0' || c > '9') {
 19         c = getchar();
 20     }
 21     while(c >= '0' && c <= '9') {
 22         x = (x << 3) + (x << 1) + c - 48;
 23         c = getchar();
 24     }
 25     return;
 26 }
 27 
 28 void add(int p, int v, int l, int r, int &o) {
 29     if(!o) {
 30         o = ++tot;
 31     }
 32     if(l == r) {
 33         sum[o] += v;
 34         return;
 35     }
 36     int mid = (l + r) >> 1;
 37     if(p <= mid) {
 38         add(p, v, l, mid, ls[o]);
 39     }
 40     else {
 41         add(p, v, mid + 1, r, rs[o]);
 42     }
 43     sum[o] = sum[ls[o]] + sum[rs[o]];
 44     return;
 45 }
 46 
 47 inline void insert(int p, int v, int id) {
 48     for(register int i = id; i <= n; i += i & (-i)) {
 49         add(p, v, 1, temp, rt[i]);
 50     }
 51     return;
 52 }
 53 
 54 inline int ask(int k, int L, int R) {
 55     for(register int i = L - 1; i >= 1; i -= i & (-i)) {
 56         vis[i] = 1;
 57         now[i] = rt[i];
 58         p[++tp] = i;
 59     }
 60     for(register int i = R; i >= 1; i -= i & (-i)) {
 61         if(!vis[i]) {
 62             vis[i] = 1;
 63             now[i] = rt[i];
 64             p[++tp] = i;
 65         }
 66     }
 67     //printf("ask : %d %d  k = %d \n", L, R, k);
 68     int l = 1, r = temp;
 69     while(l < r) {
 70         int mid = (l + r) >> 1, s = 0;
 71         for(register int i = L - 1; i >= 1; i -= i & (-i)) {
 72             s -= *(sum + (*(ls + (*(now + i)))));
 73             //printf("s -= %d \n", sum[ls[now[i]]]);
 74         }
 75         for(register int i = R; i >= 1; i -= i & (-i)) {
 76             s += *(sum + (*(ls + (*(now + i)))));
 77             //printf("s += %d \n", sum[ls[now[i]]]);
 78         }
 79         //printf("%d %d s = %d k = %d \n", l, r, s, k);
 80         if(k <= s) {
 81             for(register int i = 1; i <= tp; i++) {
 82                 *(now + (*(p + i))) = *(ls + (*(now + (*(p + i)))));
 83             }
 84             r = mid;
 85         }
 86         else {
 87             for(register int i = 1; i <= tp; i++) {
 88                 *(now + (*(p + i))) = *(rs + (*(now + (*(p + i)))));
 89             }
 90             k -= s;
 91             l = mid + 1;
 92         }
 93     }
 94     for(register int i = 1; i <= tp; i++) {
 95         vis[p[i]] = 0;
 96     }
 97     tp = 0;
 98     return r;
 99 }
100 
101 int main() {
102     int m;
103     read(n);
104     read(m);
105     for(register int i = 1; i <= n; i++) {
106         read(a[i]);
107         X[++temp] = a[i];
108     }
109     for(register int i = 1; i <= m; i++) {
110         scanf("%s", str);
111         read(node[i].x);
112         read(node[i].y);
113         if(str[0] == 'Q') {
114             read(node[i].z);
115         }
116         else {
117             node[i].f = 1;
118             X[++temp] = node[i].y;
119         }
120     }
121     std::sort(X + 1, X + temp + 1);
122     temp = std::unique(X + 1, X + temp + 1) - X - 1;
123 
124     /*for(int i = 1; i <= temp; i++) {
125         printf("%d ", X[i]);
126     }
127     puts("");*/
128 
129     for(int i = 1; i <= n; i++) {
130         a[i] = std::lower_bound(X + 1, X + temp + 1, a[i]) - X;
131         insert(a[i], 1, i);
132         //printf("insert : %d %d \n", a[i], i);
133     }
134     for(int i = 1; i <= m; i++) {
135         if(node[i].f) {
136             node[i].y = std::lower_bound(X + 1, X + temp + 1, node[i].y) - X;
137         }
138     }
139     for(register int i = 1, x, y, z; i <= m; i++) {
140         x = node[i].x;
141         y = node[i].y;
142         if(!node[i].f) {
143             z = node[i].z;
144             printf("%d\n", X[ask(z, x, y)]);
145         }
146         else {
147             insert(a[x], -1, x);
148             insert(y, 1, x);
149             a[x] = y;
150         }
151     }
152     return 0;
153 }
AC代码

 

posted @ 2019-01-25 22:47  huyufeifei  阅读(124)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜