BZOJ 1901: Zju2112 Dynamic Rankings

1901: Zju2112 Dynamic Rankings

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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

Sample Output

3
6

HINT

 

20%的数据中,m,n≤100; 40%的数据中,m,n≤1000; 100%的数据中,m,n≤10000。

 

Source

 
[Submit][Status][Discuss]

 

带修主席树(树状数组+主席树) 模板题

 

  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

posted @ 2017-01-09 08:35  YouSiki  阅读(145)  评论(0编辑  收藏  举报