板子部分除了split_val
全是在某线段树合并分裂板子交过的,应该没什么问题(但是感觉split_val
出锅了,不知道错在哪里)
我是真萌新/kk
#include<stdio.h>
struct Node
{
int l,r,lq,rq;
long long siz;
}t[16000002];
#define lq(u) t[u].lq
#define rq(u) t[u].rq
int cnt;
inline int new_node(int _l,int _r,int _lq,int _rq,long long _siz)
{
return t[++cnt]=(Node){_l,_r,_lq,_rq,_siz},cnt;
}
inline int copy_node(int u)
{
return new_node(t[u].l,t[u].r,t[u].lq,t[u].rq,t[u].siz);
}
inline void merge_node(int u,int v)
{
t[u].siz+=t[v].siz;
}
inline void push_up(int u)
{
t[u].siz=t[lq(u)].siz+t[rq(u)].siz;
}
int insert(int l,int r,int p,int u,int val)
{
if(!u) u=new_node(l,r,0,0,0);
if(t[u].l==t[u].r)
{
t[u].siz+=val;
return u;
}
int mid=(t[u].l+t[u].r)>>1;
if(p<=mid)
lq(u)=insert(l,mid,p,lq(u),val);
else
rq(u)=insert(mid+1,r,p,rq(u),val);
push_up(u);
return u;
}
void merge(int &u,int v)//°ÑvµÄÊ÷ºÏ²¢µ½uÉÏ
{
if(!(u&&v)) u|=v;
else merge(lq(u),lq(v)),merge(rq(u),rq(v)),merge_node(u,v);
}
void split_val(int u,int val,int &x,int &y)
{
if((!u)||t[u].l==t[u].r)
{
x=t[u].l==val?u:0,y=0;
return;
}
int v=copy_node(u);
x=u,y=v;
if(val<=t[lq(u)].r)
{
rq(u)=0;
split_val(lq(u),val,lq(u),lq(v));
}
else
{
lq(v)=0;
split_val(rq(u),val,rq(u),rq(v));
}
push_up(u),push_up(v);
}
int kth(int u,long long k)
{
if(!u) return -1;
if(t[u].l==t[u].r) return t[u].l;
if(k<=t[lq(u)].siz) return kth(lq(u),k);
else return kth(rq(u),k-t[lq(u)].siz);
}
long long rank(int u,int val)//СÓÚ
{
if(!u) return 0;
if(t[u].l==t[u].r) return 0;
if(val<=t[lq(u)].r) return rank(lq(u),val);
else return t[lq(u)].siz+rank(rq(u),val);
}
int root[200002],top,n,m,tk,tx,ty,tu;
int main()
{
scanf("%d%d",&n,&m);
root[1]=1;
cnt=1;
top=1;
t[1].l=1,t[1].r=n;
for(int i=1;i<=n;i++)
scanf("%d",&tx),insert(1,n,i,1,tx);
for(int i=1;i<=m;i++)
{
scanf("%d",&tk);
if(tk==0)
{
scanf("%d%d%d",&tu,&tx,&ty);
int u,v;
split_val(root[tu],tx-1,root[tu],u);
split_val(u,ty,u,v);
merge(root[tu],v);
root[++top]=u;
}
if(tk==1)
{
scanf("%d%d",&tx,&ty);
merge(root[tx],root[ty]);
}
if(tk==2)
{
scanf("%d%d%d",&tu,&tx,&ty);
insert(1,n,ty,root[tu],tx);
}
if(tk==3)
{
scanf("%d%d%d",&tu,&tx,&ty);
printf("%lld\n",rank(root[tu],ty+1)-rank(root[tu],tx));
}
if(tk==4)
{
scanf("%d%d",&tx,&ty);
printf("%d\n",kth(root[tx],ty));
}
}
return 0;
}