链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1901
题意:中文题。
分析:带修改的区间第k小,在可持久化线段树外面套一个树状数组,然后将建树的过程改点。时间O(nlognlogn)+空间T(nlognlogn)
代码:
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=11000;
const int MAX=100000000;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=998244353;
const ll INF=10000000010;
typedef double db;
typedef unsigned long long ull;
char s[N][2];
int n,m,ql[N],qr[N],qk[N],L[100],R[100];
int aa,bb,tot,top,a[2*N],num[2*N],has[2*N];
int siz,root[N],ls[200*N],rs[200*N],sum[200*N];
inline int find_p(int x) {
int l=0,r=tot,mid=tot>>1;
while (l+1<r)
if (has[mid]<x) { l=mid;mid=(l+r)>>1; }
else { r=mid;mid=(l+r)>>1; }
return r;
}
inline void init() {
scanf("%d%d", &n, &m);
for (int i=1;i<=n;i++) {
scanf("%d", &a[i]);num[++top]=a[i];
}
for (int i=1;i<=m;i++) {
scanf("%s", s[i]);
scanf("%d%d", &ql[i], &qr[i]);
if (s[i][0]=='Q') scanf("%d", &qk[i]);
else num[++top]=qr[i];
}
sort(num+1,num+top+1);
has[++tot]=num[1];
for (int i=2;i<=top;i++)
if (num[i]!=num[i-1]) has[++tot]=num[i];
}
void updata(int l,int r,int x,int &y,int z,int w) {
y=++siz;sum[y]=sum[x]+w;
ls[y]=ls[x];rs[y]=rs[x];
if (l==r) return ;
int mid=(l+r)>>1;
if (z<=mid) updata(l,mid,ls[x],ls[y],z,w);
else updata(mid+1,r,rs[x],rs[y],z,w);
}
int query(int l,int r,int k) {
if (l==r) return l;
int i,suml=0,sumr=0,mid=(l+r)>>1;
for (i=1;i<=aa;i++) suml+=sum[ls[L[i]]];
for (i=1;i<=bb;i++) sumr+=sum[ls[R[i]]];
if (k<=sumr-suml) {
for (i=1;i<=aa;i++) L[i]=ls[L[i]];
for (i=1;i<=bb;i++) R[i]=ls[R[i]];
query(l,mid,k);
} else {
for (i=1;i<=aa;i++) L[i]=rs[L[i]];
for (i=1;i<=bb;i++) R[i]=rs[R[i]];
query(mid+1,r,k-(sumr-suml));
}
}
int main()
{
int i,j;
init();
for (i=1;i<=n;i++)
for (j=i;j<=n;j+=j&(-j)) updata(1,tot,root[j],root[j],find_p(a[i]),1);
for (i=1;i<=m;i++)
if (s[i][0]=='Q') {
aa=0;bb=0;ql[i]--;
for (j=ql[i];j;j-=j&(-j)) L[++aa]=root[j];
for (j=qr[i];j;j-=j&(-j)) R[++bb]=root[j];
printf("%d\n", has[query(1,tot,qk[i])]);
} else {
for (j=ql[i];j<=n;j+=j&(-j)) updata(1,tot,root[j],root[j],find_p(a[ql[i]]),-1);
a[ql[i]]=qr[i];
for (j=ql[i];j<=n;j+=j&(-j)) updata(1,tot,root[j],root[j],find_p(a[ql[i]]),1);
}
return 0;
}