一些名字和解释:传送门
例题:zoj2112
代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=60060;
int cnt,n,m,x,y,k,tmp,root[N],spt[N],a[N];
int cmp;
struct node{int l,r,sum;}T[N*40];
struct Op{int l,r,k,type;}op[N];
vector<int>Q1,Q2;
vector<int> p;
int getid(int x) {return lower_bound(p.begin(),p.end(),x)-p.begin()+1;}
int lowbit(int x) {return -x&x;}
void update(int l,int r,int &x,int y,int pos )
{
T[++cnt]=T[y],T[cnt].sum++,x=cnt;
if(l==r) return ;
int mid=(r+l)>>1;
if(pos<=mid) update(l,mid,T[x].l,T[y].l,pos);
else update(mid+1,r,T[x].r,T[y].r,pos);
}
void insert(int l,int r,int &i,int x,int val)
{
if(i==0) T[++cnt]=T[i],i=cnt;
T[i].sum+=val;
if(l==r) return ;
int mid=(r+l)>>1;
if(x<=mid)insert(l,mid,T[i].l,x,val);
else insert(mid+1,r,T[i].r,x,val);
}
void BIT_insert(int pos,int x,int val)
{
for(int i=pos;i<=tmp;i+=lowbit(i))
insert(1,tmp,spt[i],x,val);
}
int ST_query(vector<int> Q1,vector<int> Q2,int l,int r,int k)
{
if(l==r) return l;
int c=0;
int mid=(r+l)>>1;
for(int i=0,sz=Q1.size();i<sz;i++) c-=T[T[Q1[i]].l].sum;
for(int i=0,sz=Q2.size();i<sz;i++) c+=T[T[Q2[i]].l].sum;
for(int i=0,sz=Q1.size();i<sz;i++) Q1[i]=(c>=k?T[Q1[i]].l:T[Q1[i]].r);
for(int i=0,sz=Q2.size();i<sz;i++) Q2[i]=(c>=k?T[Q2[i]].l:T[Q2[i]].r);
if(c>=k) return ST_query(Q1,Q2,l,mid,k);
else return ST_query(Q1,Q2,mid+1,r,k-c);
}
int query(int l,int r,int k)
{
Q1.clear(),Q2.clear();
Q1.push_back(root[l-1]);
Q2.push_back(root[r]);
for(int i=l-1;i>0;i-=lowbit(i)) Q1.push_back(spt[i]);
for(int i=r;i>0;i-=lowbit(i)) Q2.push_back(spt[i]);
return ST_query(Q1,Q2,1,tmp,k);
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
cnt=0;
memset(root,0,sizeof(root));
memset(spt,0,sizeof(spt));
p.clear();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),p.push_back(a[i]);
char str[4];
for(int i=1;i<=m;i++)
{
scanf("%s",str);
if(str[0]=='Q')
{
op[i].type=1;
scanf("%d%d%d",&op[i].l,&op[i].r,&op[i].k);
}
else
{
op[i].type=0;
scanf("%d%d",&op[i].l,&op[i].r);
p.push_back(op[i].r);
}
}
sort(p.begin(),p.end()),p.erase(unique(p.begin(),p.end()),p.end());
tmp=p.size();
for(int i=1;i<=n;i++) update(1,tmp,root[i],root[i-1],getid(a[i]));
for(int i=1;i<=m;i++)
{
if(op[i].type==1)
{
printf("%d\n",p[query(op[i].l,op[i].r,op[i].k)-1]);
}
else
{
BIT_insert(op[i].l,getid(a[op[i].l]),-1);
BIT_insert(op[i].l,getid(op[i].r),1);
a[op[i].l]=op[i].r;
}
}
}
}