题目链接:https://vjudge.net/problem/ZOJ-2112
多样例:
输入一个样例数t。
输入一个n和m。数组长度和操作数
Q l r k:查询区间[l, r]的第k小的数
C x y:修改a[x]=y
Sample Input
2
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
5 3
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
3
6
思路:整体二分的模板题
#include <bits/stdc++.h> using namespace std; #define LL long long const int maxn=5e5+10, maxm=1e5+10, inf=1e9+7; struct node{ int x, y, k, type, id; }q[maxn+maxm*2], q1[maxn+maxm*2], q2[maxn+maxm*2]; int n, m, tot, totx; int a[maxn], ans[maxn]; struct BitTree { LL c[maxn]; int lowbit(int p){ return (p&-p); } void Add(int x, LL v) { if (!x) return; while (x < 500005) c[x] += v, x += lowbit(x); } LL Ask(int x) { LL t = 0; while (x) t += c[x], x -= lowbit(x); return t; } LL Ask(int l, int r) { if (l > r) return 0; return Ask(r) - Ask(l - 1); } }Tree; void solve(int ql, int qr, int L, int R){ if(ql>qr) return ; if(L==R){//统计答案 for(int i=ql; i<=qr; i++){ if(q[i].type==2){ ans[q[i].id]=L; } } return ; } int mid=(L+R)>>1; int t1=0, t2=0; for(int i=ql; i<=qr; i++){//按顺序执行一边 if(q[i].type==1){//遇见修改 if(q[i].x<=mid){//<mid 对结果产生影响 Tree.Add(q[i].id, q[i].y); q1[t1++]=q[i]; } else{//不产生影响 q2[t2++]=q[i]; } } else{//遇见查询 int tt=Tree.Ask(q[i].x, q[i].y);//查询区间下标在[x, y]<=mid的数的个数 if(tt>=q[i].k) q1[t1++]=q[i];//如果>=k个 else{//如果<k个 q[i].k-=tt; q2[t2++]=q[i]; } } } for(int i=0; i<t1; i++) q[ql+i]=q1[i]; //把q1,q2的信息复制到q中 for(int i=0; i<t2; i++) q[ql+t1+i]=q2[i]; for(int i=0; i<t1; i++){ if(q1[i].type==1){ Tree.Add(q1[i].id, -q1[i].y);//把之前的标记清除 } } solve(ql, ql+t1-1, L, mid);//分治 solve(ql+t1, qr, mid+1, R); } int main(){ int T; scanf("%d", &T); while(T--){ tot=totx=0; scanf("%d%d", &n, &m); int x, y, k; char op[5]; for(int i=1; i<=n; i++){ scanf("%d", &a[i]); tot++; q[tot].x=a[i], q[tot].y=1, q[tot].type=1, q[tot].id=i; //x:值 y:添加还是删除 type:查询还是修改 id:下标 } for(int i=1; i<=m; i++){ scanf("%s", op); if(op[0]=='Q'){ scanf("%d%d%d", &x, &y, &k); tot++; q[tot].x=x, q[tot].y=y, q[tot].k=k, q[tot].type=2, q[tot].id=++totx; } else{ scanf("%d%d", &x, &y); tot++; q[tot].x=a[x]; q[tot].y=-1; q[tot].type=1, q[tot].id=x; tot++; a[x]=y; q[tot].x=a[x]; q[tot].y=1; q[tot].type=1, q[tot].id=x; } } solve(1, tot, 0, inf); for(int i=1; i<=totx; i++){ printf("%d\n", ans[i]); } } return 0; }