题目链接
题意:动态区间第k小就是静态区间第k小加上修改这个功能,静态第k小我们是用主席树做的,但是如果带上修改的功能,主席树保存的是前缀信息,所以说,当修改了一个点的时候,他后面的点都要修改,很明显时间复杂度过不去。所以就用树套树,树状数组套动态开点线段树,树状数组的时间复杂度是logn。这个题写了超久,要不是男神给我debug,估计还要两三天才能写出来。
数组数组的上限是n,不是离散化后的元素个数,因为一共有n个根节点。如果离线做这道题,需要多留一点空间。
#include
#define low(x) x&-x
#define mid (l+r)/2
using namespace std;
const int maxn=1e5+100;
int n,cnt,a[maxn],V[25],S[maxn*210],tot=0,V1[25];
int tot1=0,sz;
int sum[maxn*210],ls[maxn*210],rs[maxn*210],rt[maxn];
struct node{
char opt[2];
int ql,qr,k;
}Q[maxn];
void up(int l,int r,int p,int v)
{
for(int i=1;i<=tot;i++)
{
sum[V[i]]+=v;
}
if(l==r)return ;
if(p<=mid)
{
for(int i=1;i<=tot;i++)
{
if(!ls[V[i]])ls[V[i]]=++cnt;
V[i]=ls[V[i]];
}
up(l,mid,p,v);
}
else
{
for(int i=1;i<=tot;i++)
{
if(!rs[V[i]])rs[V[i]]=++cnt;
V[i]=rs[V[i]];
}
up(mid+1,r,p,v);
}
}
int qu(int l,int r,int k)
{
if(l==r)return S[l];
int res=0;
for(int i=1;i<=tot1;i++)
{
res+=sum[ls[V1[i]]];
}
for(int i=1;i<=tot;i++)
{
res-=sum[ls[V[i]]];
}
if(res>=k)
{
for(int i=1;i<=tot;i++)
{
V[i]=ls[V[i]];
}
for(int i=1;i<=tot1;i++)
{
V1[i]=ls[V1[i]];
}
qu(l,mid,k);
}
else
{
for(int i=1;i<=tot;i++)
{
V[i]=rs[V[i]];
}
for(int i=1;i<=tot1;i++)
{
V1[i]=rs[V1[i]];
}
qu(mid+1,r,k-res);
}
}
void modify(int x,int p,int v)
{
tot=0;
for(;x<=n;x+=low(x))
{
V[++tot]=rt[x];
}
up(1,sz,p,v);
}
void _qu(int l,int r,int k)
{
tot=0,tot1=0;
for(;l;l-=low(l))
{
V[++tot]=rt[l];
}
for(;r;r-=low(r))
{
V1[++tot1]=rt[r];
}
int ans=qu(1,sz,k);
printf("%d\n",ans);
}
int main()
{
int m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)rt[i]=++cnt;
for(int i=1;i<=n;i++)scanf("%d",a+i),S[++sz]=a[i];
for(int i=1;i<=m;i++)
{
scanf("%s",Q[i].opt);
if(Q[i].opt[0]=='C')
{
scanf("%d%d",&Q[i].ql,&Q[i].qr);
S[++sz]=Q[i].qr;
}
else
{
scanf("%d%d%d",&Q[i].ql,&Q[i].qr,&Q[i].k);
}
}
sort(S+1,S+1+sz);
sz=unique(S+1,S+1+sz)-S-1;
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(S+1,S+1+sz,a[i])-S;
modify(i, a[i], 1);
}
for(int i=1;i<=m;i++)
{
if(Q[i].opt[0]=='C')
{
modify(Q[i].ql,a[Q[i].ql],-1);
a[Q[i].ql]=lower_bound(S+1,S+1+sz,Q[i].qr)-S;
modify(Q[i].ql,a[Q[i].ql],1);
}
else if(Q[i].opt[0]=='Q')
{
_qu(Q[i].ql-1,Q[i].qr,Q[i].k);
}
}
}