BZOJ 1901: Zju2112 Dynamic Rankings
1901: Zju2112 Dynamic Rankings
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7294 Solved: 3039
[Submit][Status][Discuss]
Description
给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改变后的a继续回答上面的问题。你需要编一个这样的程序,从输入文件中读入序列a,然后读入一系列的指令,包括询问指令和修改指令。对于每一个询问指令,你必须输出正确的回答。 第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。分别表示序列的长度和指令的个数。第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。接下来的m行描述每条指令,每行的格式是下面两种格式中的一种。 Q i j k 或者 C i t Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。
Input
对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。
Output
Sample Input
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
6
HINT
20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。
Source
带修主席树(树状数组+主席树) 模板题
1 #include <bits/stdc++.h> 2 3 inline char nextChar(void) 4 { 5 static const int siz = 1024; 6 7 static char buf[siz]; 8 static char *hd = buf + siz; 9 static char *tl = buf + siz; 10 11 if (hd == tl) 12 fread(hd = buf, 1, siz, stdin); 13 14 return *hd++; 15 } 16 17 inline int nextInt(void) 18 { 19 register int ret = 0; 20 register int neg = false; 21 register int bit = nextChar(); 22 23 for (; bit < 48; bit = nextChar()) 24 if (bit == '-')neg ^= true; 25 26 for (; bit > 47; bit = nextChar()) 27 ret = ret * 10 + bit - 48; 28 29 return neg ? -ret : ret; 30 } 31 32 inline int nextOrd(void) 33 { 34 register int bit = nextChar(); 35 36 while (bit != 'Q' && bit != 'C') 37 bit = nextChar(); 38 39 return bit == 'Q'; 40 } 41 42 const int siz = 40005; 43 44 struct data 45 { 46 int k, a, b, c; 47 }s[siz]; 48 49 int n, m, num[siz]; 50 51 int map[siz], tot = 0; 52 53 inline int find(int x) 54 { 55 return std::lower_bound(map + 1, map + tot, x) - map; 56 } 57 58 inline void makeMap(void) 59 { 60 for (int i = 1; i <= n; ++i) 61 map[++tot] = num[i]; 62 63 for (int i = 1; i <= m; ++i) 64 if (!s[i].k)map[++tot] = s[i].b; 65 66 std::sort(map + 1, map + tot + 1); 67 68 tot = std::unique(map + 1, map + tot + 1) - map; 69 70 for (int i = 1; i <= n; ++i) 71 num[i] = find(num[i]); 72 73 for (int i = 1; i <= m; ++i) 74 if (!s[i].k)s[i].b = find(s[i].b); 75 } 76 77 int ls[siz * 200]; 78 int rs[siz * 200]; 79 int sz[siz * 200]; 80 81 void insert(int &t, int f, int l, int r, int p, int v) 82 { 83 static int cnt = 0; 84 85 t = ++cnt; 86 87 ls[t] = ls[f]; 88 rs[t] = rs[f]; 89 sz[t] = sz[f] + v; 90 91 if (l != r) 92 { 93 int mid = (l + r) >> 1; 94 95 if (p <= mid) 96 insert(ls[t], ls[f], l, mid, p, v); 97 else 98 insert(rs[t], rs[f], mid + 1, r, p, v); 99 } 100 } 101 102 int root[siz]; 103 104 inline void insert(int t, int p, int v) 105 { 106 for (; t <= tot; t += t&-t) 107 insert(root[t], root[t], 1, tot, p, v); 108 } 109 110 int node[siz], tims[siz], tail; 111 112 inline void push(int t, int k) 113 { 114 for (; t >= 1; t -= t&-t) 115 { 116 node[tail] = root[t]; 117 tims[tail++] = k; 118 } 119 } 120 121 int query(int l, int r, int k) 122 { 123 if (l == r)return l; 124 125 int sum = 0, mid = (l + r) >> 1; 126 127 for (int i = 0; i < tail; ++i) 128 sum += tims[i] * sz[ls[node[i]]]; 129 130 if (sum >= k) 131 { 132 for (int i = 0; i < tail; ++i) 133 node[i] = ls[node[i]]; 134 135 return query(l, mid, k); 136 } 137 else 138 { 139 for (int i = 0; i < tail; ++i) 140 node[i] = rs[node[i]]; 141 142 return query(mid + 1, r, k - sum); 143 } 144 } 145 146 signed main(void) 147 { 148 n = nextInt(); 149 m = nextInt(); 150 151 for (int i = 1; i <= n; ++i) 152 num[i] = nextInt(); 153 154 for (int i = 1; i <= m; ++i) 155 { 156 if (s[i].k = nextOrd()) 157 { 158 s[i].a = nextInt(); 159 s[i].b = nextInt(); 160 s[i].c = nextInt(); 161 } 162 else 163 { 164 s[i].a = nextInt(); 165 s[i].b = nextInt(); 166 } 167 } 168 169 makeMap(); 170 171 for (int i = 1; i <= n; ++i) 172 insert(i, num[i], 1); 173 174 for (int i = 1; i <= m; ++i) 175 { 176 if (s[i].k) 177 { 178 tail = 0; 179 push(s[i].b, 1); 180 push(s[i].a - 1, -1); 181 printf("%d\n", map[query(1, tot, s[i].c)]); 182 } 183 else 184 { 185 insert(s[i].a, num[s[i].a], -1); 186 num[s[i].a] = s[i].b; 187 insert(s[i].a, num[s[i].a], 1); 188 } 189 } 190 }
@Author: YouSiki