数据结构:树套树-权值线段树套线段树
有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<algorithm> 5 #include<cstring> 6 #define ll long long 7 using namespace std; 8 int read() 9 { 10 int x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 int a,b,c; 16 int n,m,sz; 17 int root[200005]; 18 int ls[20000005],rs[20000005],sum[20000005],lazy[20000005]; 19 void pushdown(int k,int l,int r) 20 { 21 if(!lazy[k]||l==r)return; 22 if(!ls[k])ls[k]=++sz; 23 if(!rs[k])rs[k]=++sz; 24 lazy[ls[k]]+=lazy[k];lazy[rs[k]]+=lazy[k]; 25 int mid=(l+r)>>1; 26 sum[ls[k]]+=(mid-l+1)*lazy[k]; 27 sum[rs[k]]+=(r-mid)*lazy[k]; 28 lazy[k]=0; 29 } 30 void modify(int &k,int l,int r,int a,int b) 31 { 32 if(!k)k=++sz; 33 pushdown(k,l,r); 34 if(l==a&&r==b) 35 { 36 sum[k]+=r-l+1; 37 lazy[k]++; 38 return; 39 } 40 int mid=(l+r)>>1; 41 if(b<=mid)modify(ls[k],l,mid,a,b); 42 else if(a>mid)modify(rs[k],mid+1,r,a,b); 43 else 44 { 45 modify(ls[k],l,mid,a,mid);modify(rs[k],mid+1,r,mid+1,b); 46 } 47 sum[k]=sum[ls[k]]+sum[rs[k]]; 48 } 49 int query(int k,int l,int r,int a,int b) 50 { 51 if(!k)return 0; 52 pushdown(k,l,r); 53 if(l==a&&r==b)return sum[k]; 54 int mid=(l+r)>>1; 55 if(b<=mid)return query(ls[k],l,mid,a,b); 56 else if(a>mid)return query(rs[k],mid+1,r,a,b); 57 else return query(ls[k],l,mid,a,mid)+query(rs[k],mid+1,r,mid+1,b); 58 } 59 void insert() 60 { 61 int k=1,l=1,r=n; 62 while(l!=r) 63 { 64 int mid=(l+r)>>1; 65 modify(root[k],1,n,a,b); 66 if(c<=mid)r=mid,k=k<<1; 67 else l=mid+1,k=k<<1|1; 68 } 69 modify(root[k],1,n,a,b); 70 } 71 int solve() 72 { 73 int l=1,r=n,k=1; 74 while(l!=r) 75 { 76 int mid=(l+r)>>1; 77 int t=query(root[k<<1],1,n,a,b); 78 if(t>=c)r=mid,k<<=1; 79 else l=mid+1,k=k<<1|1,c-=t; 80 } 81 return l; 82 } 83 int main() 84 { 85 n=read();m=read(); 86 while(m--) 87 { 88 int f=read();a=read();b=read();c=read(); 89 if(f==1) 90 { 91 c=n-c+1;insert(); 92 } 93 else printf("%d\n",n-solve()+1); 94 } 95 return 0; 96 }