空间开大会MLE,开小会RE。
// Problem: P2617 Dynamic Rankings
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2617
// Memory Limit: 512 MB
// Time Limit: 3000 ms
#include<stdio.h>
bool ed;
const int maxn = 3.2e7+7;
const int minv = 0;
const int maxv = 1e9+7;
// const int maxv = 1000000027;
namespace vseg {
struct Node {
int count, sum, l, r;
} tree[maxn];
int cnt = 1;
int newnode() { return ++cnt; }
inline void update(int index) { tree[index].sum = tree[index].count + tree[tree[index].l].sum + tree[tree[index].r].sum; }
void assert_val(bool val, char* failed) { if(not val) printf("%s FAILED.\n", failed); }
void add(int index, int l, int r, int ind, int v) {
if(l == r){
assert_val(l==ind, "add::final_position");
tree[index].count+=v, tree[index].sum+=v;
return;
}
int mid = (l+r)>>1;
if(ind <= mid) {
if(not tree[index].l)
tree[index].l = newnode();
add(tree[index].l, l, mid, ind, v);
}
else {
if(not tree[index].r)
tree[index].r = newnode();
add(tree[index].r, mid+1, r, ind, v);
}
update(index);
}
int rank(int index, int l, int r, int remain){
if(l == r)
return l;
int mid = (l+r)>>1;
if(tree[index].l and tree[index].r){
if(remain-tree[tree[index].l].sum > 0)
return rank(tree[index].r, mid+1, r, remain-tree[tree[index].l].sum);
else
return rank(tree[index].l, l, mid, remain);
return 0;
}
else
if(tree[index].l)
return rank(tree[index].l, l, mid, remain);
else
return rank(tree[index].r, mid+1, r, remain);
}
int sum(int index, int l, int r, int ql, int qr){
if(ql <= l and r <= qr)
return tree[index].sum;
if(l > qr or r < ql)
return 0;
int mid = (l+r)>>1, res = 0;
if(tree[index].l)
res += sum(tree[index].l, l, mid, ql, qr);
if(tree[index].r)
res += sum(tree[index].r, mid+1, r, ql, qr);
return res;
}
}
struct segt {
int root;
segt() { root = vseg::newnode(); }
inline void add(int x) { vseg::add(root, minv, maxv, x, 1); }
inline void rem(int x) { vseg::add(root, minv, maxv, x, -1); }
inline int rank(int x) { return vseg::sum (root, minv, maxv, minv, x-1) + 1; }
inline int kth (int x) { return vseg::rank(root, minv, maxv, x); }
inline int pre (int x) { return vseg::rank(root, minv, maxv, vseg::sum(1, minv, maxv, minv, x-1)); }
inline int nxt (int x) { return vseg::rank(root, minv, maxv, vseg::sum(1, minv, maxv, minv, x) + 1); }
inline int size(int x) { return vseg::tree[root].sum; }
};
const int tmaxn = 4.1e5;
int li[tmaxn];
segt tree[tmaxn];
void build(int index, int l, int r){
// printf("%d, [%d, %d]\n", index, l, r);
for(int i=l; i<=r; i++){
// printf("%d add %d\n", index, li[i]);
tree[index].add(li[i]);
}
if(l==r)
return;
int mid = (l+r)>>1;
build(index<<1 , l, mid);
build(index<<1|1, mid+1, r);
}
void modify(int index, int l, int r, int pos, int pre, int v){
if(l <= pos and pos <= r)
// printf("%d modify %d %d\n", index, pre, v),
tree[index].rem(pre),
tree[index].add(v);
if(l == r) return;
int mid = (l+r)>>1;
modify(index<<1 , l, mid, pos, pre, v);
modify(index<<1|1, mid+1, r, pos, pre, v);
}
int rank(int index, int l, int r, int ql, int qr, int k){
if(l > qr or r < ql)
return 0;
if(ql <= l and r <= qr)
return tree[index].rank(k)-1;
int mid = (l+r) >> 1;
return rank(index<<1, l, mid, ql, qr, k) + rank(index<<1|1, mid+1, r, ql, qr, k);
}
int n, m, u, v, w;
int queryk(int ql, int qr, int k){
int l = minv, r = maxv;
while(r-l>1){
int mid = (l+r)>>1;
// printf("%d, %d val = %d, rank = %d\n", l, r, mid, rank(1, 1, n, ql, qr, mid) + 1);
if(rank(1, 1, n, ql, qr, mid) + 1 <= k)
l = mid;
else
r = mid;
}
for(int i=r;i>=l;i--)
if(rank(1, 1, n, ql, qr, i)+1 <= k)
return i;
printf("WHAR???\n");
}
bool bg;
char ch;
int main(){
#ifdef debug_rickyxrc
fprintf(stderr, "Mem usage : %.4lf KB\n", (&ed-&bg) /1024.0);
fprintf(stderr, "Mem usage : %.4lf MB\n", (&ed-&bg) /1024.0/1024.0);
#endif
scanf("%d%d", &n, &m);
for(int i=1;i<=n;i++)
scanf("%d", li+i);
build(1, 1, n);
// printf("%d\n", rank(1, 1, n, 1, 4, 9) + 1);
for(int i=1;i<=m;i++){
do
ch=getchar();
while(ch!='Q' and ch!='C');
if(ch == 'Q')
scanf("%d%d%d", &u, &v, &w),
printf("%d\n", queryk(u, v, w));
else
scanf("%d%d", &u, &v),
modify(1, 1, n, u, li[u], v),
li[u] = v;
}
return 0;
}