树套树的空间要开多大?
另外为什么我的代码要开 2×107 才能过,题解好像只开了 2×106,代码见下:
#include<iostream>
#include<algorithm>
using namespace std;
const int N=5e4+10,M=2e7+10; int n,tot,a[N],lc[M],rc[M]; unsigned int val[M],lzy[M];
struct Query { int opt,l,r; long long c; }q[N];
struct SGT {
int rt;
void pushup(int u) { val[u]=val[lc[u]]+val[rc[u]]; }
void pushdown(int u,int l,int r) {
if(l==r||!lzy[u]) return;
int m=(l+r)>>1;
if(!lc[u]) lc[u]=++tot;
val[lc[u]]+=(m-l+1)*lzy[u],lzy[lc[u]]+=lzy[u];
if(!rc[u]) rc[u]=++tot;
val[rc[u]]+=(r-m)*lzy[u],lzy[rc[u]]+=lzy[u];
lzy[u]=0;
}
void update(int &u,int l,int r,int ul,int ur,int x) {
if(ul>r||ur<l) return;
if(!u) u=++tot;
if(ul<=l&&r<=ur) return val[u]+=(r-l+1)*x,lzy[u]+=x,void();
pushdown(u,l,r); int m=(l+r)>>1;
update(lc[u],l,m,ul,ur,x),update(rc[u],m+1,r,ul,ur,x);
pushup(u);
}
unsigned int query(int &u,int l,int r,int ql,int qr) {
if(ql>r||qr<l) return 0;
if(!u) u=++tot;
if(ql<=l&&r<=qr) return val[u];
pushdown(u,l,r); int m=(l+r)>>1;
return query(lc[u],l,m,ql,qr)+query(rc[u],m+1,r,ql,qr);
}
}tree[N<<2];
void change(int u,int L,int R,int l,int r,int c) {
tree[u].update(tree[u].rt,1,n,l,r,1);
if(L==R) return;
int m=(L+R)>>1;
if(c<=m) change(u<<1,L,m,l,r,c);
else change(u<<1|1,m+1,R,l,r,c);
}
int get_kth(int u,int L,int R,int l,int r,long long c) {
if(L==R) return L;
int m=(L+R)>>1; unsigned int p=tree[u<<1|1].query(tree[u<<1|1].rt,1,n,l,r);
if(c>p) return get_kth(u<<1,L,m,l,r,c-p);
return get_kth(u<<1|1,m+1,R,l,r,c);
}
int main() {
ios::sync_with_stdio(false),cin.tie(nullptr);
int m,cnt=0; cin>>n>>m;
for(int i=1;i<=m;i++) {
cin>>q[i].opt>>q[i].l>>q[i].r>>q[i].c;
if(q[i].opt==1) a[++cnt]=q[i].c;
}
sort(a+1,a+cnt+1),cnt=unique(a+1,a+cnt+1)-a-1;
for(int i=1;i<=m;i++) {
if(q[i].opt==1) q[i].c=lower_bound(a+1,a+cnt+1,q[i].c)-a,change(1,1,cnt,q[i].l,q[i].r,q[i].c);
else cout<<a[get_kth(1,1,cnt,q[i].l,q[i].r,q[i].c)]<<'\n';
}
return 0;
}