一般需要离散化
无离散化模板
const int MAX_N=100100;
int n,m,num=0,len;
int a[MAX_N];
int root[MAX_N],root1[MAX_N],lc[MAX_N],rc[MAX_N],lcnt,rcnt,nn;
struct skt{
int l,r,sum;
}f[MAX_N*400];
void locate(int l,int r){
lcnt=0;rcnt=0;
while(l){
lc[++lcnt]=root1[l];
l-=(l&-l);
}
while(r){
rc[++rcnt]=root1[r];
r-=(r&-r);
}
}
void add(int k,int k1,int l,int r,int x,int val){
if(l==r){
f[k1].sum=f[k].sum;
f[k1].sum+=val;
return;
}
int mid=(l+r)>>1;
if(x<=mid){
f[k1].l=++num;
f[k1].r=f[k].r;
add(f[k].l,f[k1].l,l,mid,x,val);
}
else{
f[k1].l=f[k].l;
f[k1].r=++num;
add(f[k].r,f[k1].r,mid+1,r,x,val);
}
f[k1].sum=f[f[k1].l].sum+f[f[k1].r].sum;
}
void change(int p,int x,int y){
while(p<=n){
int ca=root1[p];
root1[p]=++num;
add(ca,root1[p],1,len,x,-1);
ca=root1[p];
root1[p]=++num;
add(ca,root1[p],1,len,y,1);
p+=(p&-p);
}
}
int ask(int k,int k1,int l,int r,int x){
int i;
if(l==r)
return l;
int mid=(l+r)>>1;
int ans=0;
for(i=1;i<=lcnt;i++){
ans-=f[f[lc[i]].l].sum;
}
for(i=1;i<=rcnt;i++){
ans+=f[f[rc[i]].l].sum;
}
ans+=f[f[k1].l].sum-f[f[k].l].sum;
if(ans>=x){
for(i=1;i<=lcnt;i++)
lc[i]=f[lc[i]].l;
for(i=1;i<=rcnt;i++)
rc[i]=f[rc[i]].l;
return ask(f[k].l,f[k1].l,l,mid,x);
}
else{
for(i=1;i<=lcnt;i++)
lc[i]=f[lc[i]].r;
for(i=1;i<=rcnt;i++)
rc[i]=f[rc[i]].r;
return ask(f[k].r,f[k1].r,mid+1,r,x-ans);
}
}
用法
for(i=0;i<m;i++){
scanf("%d",&op);
if(op==0){//修改
scanf("%d%d",&x,&y);
int ca=a[x];
a[x]=y;
change(x,ca,y);
}
else{//查询
scanf("%d%d%d",&x,&y,&k);
locate(x-1,y);
printf("%d\n",ans[ask(root[x-1],root[y],1,len,k)]);
}
}
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAX_N=100100;
int n,m,num=0,len;
int a[MAX_N],b[MAX_N],sub_a[MAX_N<<1],ans[MAX_N<<1];
int root[MAX_N],root1[MAX_N],lc[MAX_N],rc[MAX_N],lcnt,rcnt,nn;
struct skt{
int l,r,sum;
}f[MAX_N*400];
void locate(int l,int r){
lcnt=0;rcnt=0;
while(l){
lc[++lcnt]=root1[l];
l-=(l&-l);
}
while(r){
rc[++rcnt]=root1[r];
r-=(r&-r);
}
}
void add(int k,int k1,int l,int r,int x,int val){
if(l==r){
f[k1].sum=f[k].sum;
f[k1].sum+=val;
return;
}
int mid=(l+r)>>1;
if(x<=mid){
f[k1].l=++num;
f[k1].r=f[k].r;
add(f[k].l,f[k1].l,l,mid,x,val);
}
else{
f[k1].l=f[k].l;
f[k1].r=++num;
add(f[k].r,f[k1].r,mid+1,r,x,val);
}
f[k1].sum=f[f[k1].l].sum+f[f[k1].r].sum;
}
void change(int p,int x,int y){
while(p<=n){
int ca=root1[p];
root1[p]=++num;
add(ca,root1[p],1,len,x,-1);
ca=root1[p];
root1[p]=++num;
add(ca,root1[p],1,len,y,1);
p+=(p&-p);
}
}
int ask(int k,int k1,int l,int r,int x){
int i;
if(l==r)
return l;
int mid=(l+r)>>1;
int ans=0;
for(i=1;i<=lcnt;i++){
ans-=f[f[lc[i]].l].sum;
}
for(i=1;i<=rcnt;i++){
ans+=f[f[rc[i]].l].sum;
}
ans+=f[f[k1].l].sum-f[f[k].l].sum;
if(ans>=x){
for(i=1;i<=lcnt;i++)
lc[i]=f[lc[i]].l;
for(i=1;i<=rcnt;i++)
rc[i]=f[rc[i]].l;
return ask(f[k].l,f[k1].l,l,mid,x);
}
else{
for(i=1;i<=lcnt;i++)
lc[i]=f[lc[i]].r;
for(i=1;i<=rcnt;i++)
rc[i]=f[rc[i]].r;
return ask(f[k].r,f[k1].r,mid+1,r,x-ans);
}
}
struct node{
int op,x,y,k;
}que[MAX_N];
int main(void){
int i;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
sub_a[i-1]=a[i];
}
string s;
int cntt=n;
for(i=0;i<m;i++){
cin>>s;
if(s[0]=='Q')
que[i].op=1;
else
que[i].op=0;
if(que[i].op==1){
scanf("%d%d%d",&que[i].x,&que[i].y,&que[i].k);
}
else{
scanf("%d%d",&que[i].x,&que[i].y);
sub_a[cntt]=que[i].y;
cntt++;
}
}
sort(sub_a,sub_a+cntt);
int nn=unique(sub_a,sub_a+cntt)-sub_a;
for(i=1;i<=n;i++){
b[i]=lower_bound(sub_a,sub_a+nn,a[i])-sub_a+1;
ans[b[i]]=a[i];
}
len=nn;
for(i=1;i<=n;i++){
root[i]=++num;
add(root[i-1],root[i],1,len,b[i],1);
}
int cnt=n;
for(i=0;i<m;i++){
if(que[i].op==0){
cnt++;
int ca=b[que[i].x];
b[que[i].x]=lower_bound(sub_a,sub_a+nn,que[i].y)-sub_a+1;
ans[b[que[i].x]]=que[i].y;
change(que[i].x,ca,b[que[i].x]);
}
else{
locate(que[i].x-1,que[i].y);
printf("%d\n",ans[ask(root[que[i].x-1],root[que[i].y],1,len,que[i].k)]);
}
}
return 0;
}
651

被折叠的 条评论
为什么被折叠?



