树套树留坑
线段树套线段树:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
#include<map>
#include<bitset>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dwn(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
typedef long long ll;
const int N=50000,M=50000*16*16;
int n,m;
int tot=0,rt[N*4+10],tl[M+10],tr[M+10],add[M+10];
ll sum[M+10];
int cnt=0;
struct node
{
int val,id;
}b[N+10];
struct Q
{
int op,l,r;ll k;
}q[N+10];
template<typename T> inline void read(T &x)
{
x=0;int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
x=x*f;
}
bool cmp(node a,node b)
{
return a.val<b.val;
}
void ask_add(int &k,int l,int r,int ql,int qr)
{
if(!k) k=++tot;
sum[k]+=min(r,qr)-max(l,ql)+1;
if(ql<=l&&r<=qr)
{
add[k]++;
return;
}
int mid=(l+r)>>1;
if(ql<=mid) ask_add(tl[k],l,mid,ql,qr);
if(qr>=mid+1) ask_add(tr[k],mid+1,r,ql,qr);
}
ll ask_sum(int &k,int l,int r,int ql,int qr,int d=0)
{
if(!k) return d*(min(r,qr)-max(l,ql)+1);
if(ql<=l&&r<=qr) return sum[k]+d*(r-l+1);
ll val=0;
int mid=(l+r)>>1;
if(ql<=mid) val+=ask_sum(tl[k],l,mid,ql,qr,d+add[k]);
if(qr>=mid+1) val+=ask_sum(tr[k],mid+1,r,ql,qr,d+add[k]);
return val;
}
void insert(int k,int l,int r,int ql,int qr,int d)
{
ask_add(rt[k],1,n,ql,qr);
if(l==r) return;
int mid=(l+r)>>1;
if(d<=mid) insert(k<<1,l,mid,ql,qr,d);
else insert(k<<1|1,mid+1,r,ql,qr,d);
}
int kth(int k,int l,int r,int ql,int qr,ll d)
{
if(l==r) return l;
int mid=(l+r)>>1;
ll rcnt=ask_sum(rt[k<<1|1],1,n,ql,qr);
if(rcnt<d) return kth(k<<1,l,mid,ql,qr,d-rcnt);
else return kth(k<<1|1,mid+1,r,ql,qr,d);
}
inline void init()
{
sort(b+1,b+cnt+1,cmp);
int i=1,j=1;
while(j<=cnt)
{
b[i]=b[j];
while(b[i].val==b[j].val&&j<=cnt) q[b[j++].id].k=i;
++i;
}
cnt=i-1;
}
int main()
{
read(n),read(m);
rep(i,1,m)
{
read(q[i].op),read(q[i].l),read(q[i].r),read(q[i].k);
if(q[i].op==1) b[++cnt].val=q[i].k,b[cnt].id=i;
}
init();
rep(i,1,m)
{
if(q[i].op==1) insert(1,1,cnt,q[i].l,q[i].r,q[i].k);
if(q[i].op==2) printf("%d
",b[kth(1,1,cnt,q[i].l,q[i].r,q[i].k)].val);
}
return 0;
}