这题我在学校的OJ上A掉了,在BZOJ上WA了……很神奇
但是还是发一下代码吧,如果有什么错误欢迎各位老司机们指出
是一个树套树,外围像区间K大一样维护一个权值线段树,内部维护一个线段树记录这个值出现在哪些区间上
#include<cstdio> #include<algorithm> using namespace std; int n,m,cnt,root[500005]; struct SegTree{ int nl,nr,l,r,sum,tag; }tree[20000005]; void Pushdown(int rt){ if(tree[rt].tag && tree[rt].l!=tree[rt].r){ int mid=tree[rt].l+tree[rt].r>>1; if(!tree[rt].nl){tree[rt].nl=++cnt;tree[tree[rt].nl].l=tree[rt].l;tree[tree[rt].nl].r=mid;} if(!tree[rt].nr){tree[rt].nr=++cnt;tree[tree[rt].nr].l=mid+1;tree[tree[rt].nr].r=tree[rt].r;} tree[tree[rt].nl].tag+=tree[rt].tag; tree[tree[rt].nr].tag+=tree[rt].tag; tree[tree[rt].nl].sum+=(tree[tree[rt].nl].r-tree[tree[rt].nl].l+1)*tree[rt].tag; tree[tree[rt].nr].sum+=(tree[tree[rt].nr].r-tree[tree[rt].nr].l+1)*tree[rt].tag; tree[rt].tag=0; } } void Pushup(int rt){ tree[rt].sum=tree[tree[rt].nl].sum+tree[tree[rt].nr].sum; } void Modify(int &rt,int l,int r,int L,int R){ if(!rt){rt=++cnt;tree[rt].l=l;tree[rt].r=r;} Pushdown(rt); if(L<=tree[rt].l && tree[rt].r<=R){ tree[rt].sum+=tree[rt].r-tree[rt].l+1; tree[rt].tag++; return; } int mid=tree[rt].l+tree[rt].r>>1; if(L<=mid)Modify(tree[rt].nl,l,mid,L,R); if(R>mid)Modify(tree[rt].nr,mid+1,r,L,R); Pushup(rt); } int Query(int rt,int l,int r){ if(!rt)return 0; Pushdown(rt); if(l<=tree[rt].l && tree[rt].r<=r){return tree[rt].sum;} int mid=tree[rt].l+tree[rt].r>>1,ans=0; if(l<=mid)ans+=Query(tree[rt].nl,l,r); if(r>mid)ans+=Query(tree[rt].nr,l,r); Pushup(rt); return ans; } void Insert(int l,int r,int v){ int L=1,R=n,rt=1; while(L!=R){ int mid=L+R>>1; Modify(root[rt],1,n,l,r); if(v<=mid){R=mid;rt*=2;} else {L=mid+1;rt=rt*2+1;} } Modify(root[rt],1,n,l,r); } int Ask(int l,int r,int k){ int L=1,R=n,rt=1; while(L!=R){ int mid=L+R>>1; int ans=Query(root[rt*2],l,r); if(ans>=k){R=mid;rt*=2;} else {L=mid+1;rt=rt*2+1;k-=ans;} } return L; } int main(){ freopen("3110.in","r",stdin); freopen("3110.out","w",stdout); scanf("%d %d",&n,&m); for(int i=1;i<=m;i++){ int opt,a,b,c; scanf("%d %d %d %d",&opt,&a,&b,&c); if(opt==1)Insert(a,b,n-c+1); if(opt==2)printf("%d\n",n-Ask(a,b,c)+1); } return 0; }