有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
第一行N,M
接下来M行,每行形如1 a b c或2 a b c
输出每个询问的结果
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; const int MAXN=50000; int n,m=0,k,root[MAXN<<2],tp,l,r,c,num=0,p,ch; struct tree{ int l,r,s,ta; } t[20000005]; inline int read(){ p=0;ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') p=p*10+ch-48, ch=getchar(); return p; } inline int an(int x,int l,int r,int a,int b){ if (l==a&&r==b) return t[x].s; int mid=l+r>>1; if (b<=mid) return an(t[x].l,l,mid,a,b)+(b-a+1)*t[x].ta;else if (a>mid) return an(t[x].r,mid+1,r,a,b)+(b-a+1)*t[x].ta;else return an(t[x].l,l,mid,a,mid)+an(t[x].r,mid+1,r,mid+1,b)+(b-a+1)*t[x].ta; } inline int ask(int a,int b,int c){ int l=1,r=n,mid,k=1,t; while(l<r){ mid=l+r>>1; k<<=1;k|=1; t=an(root[k],1,n,a,b); if (t<c) r=mid,k^=1,c-=t;else l=mid+1; } return l; } inline void ins(int &k,int l,int r,int a,int b){ if (!k) k=++num; t[k].s+=b-a+1; if (l==a&&r==b){ t[k].ta++; return; } int mid=l+r>>1; if (b<=mid) ins(t[k].l,l,mid,a,b);else if (a>mid) ins(t[k].r,mid+1,r,a,b);else ins(t[k].l,l,mid,a,mid),ins(t[k].r,mid+1,r,mid+1,b); } inline void in(int a,int b,int c){ int l=1,r=n,k=1,mid; while(l<r){ mid=l+r>>1; ins(root[k],1,n,a,b); k<<=1; if (c<=mid) r=mid;else k|=1,l=mid+1; } ins(root[k],1,n,a,b); } int main(){ n=read();m=read(); while(m--){ tp=read();l=read();r=read();c=read(); if (tp==1) in(l,r,c);else printf("%d\n",ask(l,r,c)); } }