- 学术区
洛谷树套树WA20pts求条
- @ 2025-11-22 19:18:52
#include<bits/stdc++.h>
using namespace std;
const int maxn=2000000;
struct Node{
int ls,rs,cnt;
}t[maxn*21];
int root[maxn],tot,n,m,a[maxn],b[maxn],tot2=0,stot=0;//tot2:离散化
int clone(int p){//旧点
t[++tot]=t[p];
return tot;
}
int getrank(int x){return lower_bound(b+1,b+tot2+1,x)-b;}//映射
int getnum(int x){return b[x];}
void build(int &id,int l,int r){//加&更新新版本节点编号
if(l==r)return;
int mid=(l+r)>>1;
build(t[id].ls,l,mid);
build(t[id].rs,mid+1,r);
}//没有动态开点
void up(int id){t[id].cnt=t[t[id].ls].cnt+t[t[id].rs].cnt;}
void update(int &id,int l,int r,int x,int val){//x:修改的对应值(因为是维护的是值域)
if(x>r||x<l)return;//无交集
id=clone(id);
if(l==r){
t[id].cnt+=val;
return;
}
int mid=(l+r)>>1;
update(t[id].ls,l,mid,x,val);
update(t[id].rs,mid+1,r,x,val);
up(id);
}
int query(vector<int> p,vector<int> q,int l,int r,int k){//root l-1,root r
//树状数组需要p,因为需要统计[1,l-1]和[1,r]的贡献
if(l==r)return l;
int c=0,lcnt=0,rcnt=0;
for(auto i:p)lcnt+=t[t[i].ls].cnt;
for(auto i:q)rcnt+=t[t[i].ls].cnt;
c=rcnt-lcnt;
int mid=(l+r)>>1;
if(k<=c){
for(int i=0;i<p.size();i++)p[i]=t[p[i]].ls;
for(int i=0;i<q.size();i++)q[i]=t[q[i]].ls;
return query(p,q,l,mid,k);
}
else{
for(int i=0;i<p.size();i++)p[i]=t[p[i]].rs;
for(int i=0;i<q.size();i++)q[i]=t[q[i]].rs;
return query(p,q,mid+1,r,k-c);
}
}
int query2(vector<int> p,vector<int> q,int l,int r,int ql,int qr){//查询[ql,qr]区间内的数的个数
if(ql>r||qr<l)return 0;
int lcnt=0,rcnt=0;
for(auto i:p)lcnt+=t[i].cnt;
for(auto i:q)rcnt+=t[i].cnt;
if(ql<=l&&r<=qr){
return rcnt-lcnt;
}
int mid=(l+r)>>1;
vector<int> lp,lq,rp,rq;
for(auto i:p){
lp.push_back(t[i].ls);
rp.push_back(t[i].rs);
}
for(auto i:q){
lq.push_back(t[i].ls);
rq.push_back(t[i].rs);
}
return query2(lp,lq,l,mid,ql,qr)+query2(rp,rq,mid+1,r,ql,qr);
}
int lowbit(int x){return x&-x;}
void modify(int x,int y,int val){
int gy=getrank(y);
for(int i=x;i<=n;i+=lowbit(i)){
update(root[i],1,tot2,gy,val);
}
}
int ask(int l,int r,int k){//查询排名为k的数(区间内第k小的数)
vector<int> p,q;
for(int i=l-1;i;i-=lowbit(i))p.push_back(root[i]);
for(int i=r;i;i-=lowbit(i))q.push_back(root[i]);
return query(p,q,1,tot2,k);
}
int ask2(int l,int r,int k){//查询区间内小于等于k的数的个数
vector<int> p,q;
for(int i=l-1;i;i-=lowbit(i))p.push_back(root[i]);
for(int i=r;i;i-=lowbit(i))q.push_back(root[i]);
int g=getrank(k);
if(g<1)return 0;
return query2(p,q,1,tot2,1,g);
}
void lsh(){
sort(b+1,b+tot2+1);
tot2=unique(b+1,b+tot2+1)-b-1;
}
struct op{
int type,a,b,c;
op(){a=b=c=0;}
op(char tp,int l,int r,int k){type=tp,a=l,b=r,c=k;}
op(char tp,int x,int y){type=tp,a=x,b=y;}
}opr[maxn];
int optot=0,sroot;
void build2(int N){for(int i=1;i<=N;i++)modify(i,a[i],1);}//插入
void del(int x,int v){modify(x,v,-1);}
void ins(int x,int v){modify(x,v,1);}
void change(int pos,int k){
del(pos,a[pos]);
a[pos]=k;
ins(pos,a[pos]);
}
int kth(int l,int r,int k){return getnum(ask(l,r,k));}//查询排名为k的数
int q_rank(int l,int r,int x){
return ask2(l,r,x-1);
}
int pre(int l,int r,int x){
int rk=q_rank(l,r,x-1);//严格小于x的排名
if(!rk)return INT_MIN;;
return kth(l,r,rk);
}
int suf(int l,int r,int x){
int rk=q_rank(l,r,x)+1;//严格大于x的排名
if(rk>r-l+1)return INT_MAX;
return kth(l,r,rk);
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
b[++tot2]=a[i];
}
for(int i=1;i<=m;i++){
int opt,l,r,k,pos;
cin>>opt;
if(opt==1){//ranking
cin>>l>>r>>k;
opr[++optot]=op(1,l,r,k);
}
else if(opt==2){//k-th
cin>>l>>r>>k;
opr[++optot]=op(2,l,r,k);
}
else if(opt==3){//modify
cin>>pos>>k;
opr[++optot]=op(3,pos,k);
b[++tot2]=k;
}
else if(opt==4){
cin>>l>>r>>k;
opr[++optot]=op(4,l,r,k);
}
else if(opt==5){
cin>>l>>r>>k;
opr[++optot]=op(5,l,r,k);
}
}
lsh();
build(root[0],1,tot2);
build2(n);
for(int i=1;i<=optot;i++){
if(opr[i].type==1){
int l=opr[i].a,r=opr[i].b,k=opr[i].c;
cout<<q_rank(l,r,k)<<endl;
}
else if(opr[i].type==2){
int l=opr[i].a,r=opr[i].b,k=opr[i].c;
cout<<kth(l,r,k)<<endl;
}
else if(opr[i].type==3){//modify
int x=opr[i].a,y=opr[i].b;
change(x,y);
}
else if(opr[i].type==4){
int l=opr[i].a,r=opr[i].b,k=opr[i].c;
cout<<pre(l,r,k)<<endl;
}
else if(opr[i].type==5){
int l=opr[i].a,r=opr[i].b,k=opr[i].c;
cout<<suf(l,r,k)<<endl;
}
}
return 0;
}
0 条评论
目前还没有评论...