萌新刚学OI,除了test11全WA求救
查看原帖
萌新刚学OI,除了test11全WA求救
152213
Querainykkksd15楼主2020/5/1 22:28

板子部分除了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;
}
2020/5/1 22:28
加载中...