求助 splay TLE
查看原帖
求助 splay TLE
64974
Tirpitz__楼主2021/6/26 20:59
#include<bits/stdc++.h>
#include<windows.h>
using namespace std;
const int N=1e6+5;
struct Node{
	int s[2],p,v;  //s[0]为左儿子 s[1]为右儿子 p为父亲 v为权值 
	int size,flag;
	void init(int _v,int _p)
	{
		v=_v,p=_p;
		size=1;
	}
}tr[N]; 
int root,idx,n,m;
void pushup(int x)
{
	tr[x].size=tr[tr[x].s[0]].size+tr[tr[x].s[1]].size+1;
}
void pushdown(int x) //传翻转标记
{
	if(tr[x].flag)
	{
		swap(tr[x].s[0],tr[x].s[1]);
		tr[tr[x].s[0]].flag^=1;
		tr[tr[x].s[1]].flag^=1;
		tr[x].flag=0;
	}
}
void rotate(int x)
{
	int y=tr[x].p,z=tr[y].p;
	int k=(tr[y].s[1]==x);
	tr[z].s[tr[z].s[1]==y]=x;tr[x].p=z;
	tr[y].s[k]=tr[x].s[k^1];tr[tr[x].s[k^1]].p=y;
	tr[y].p=x;tr[x].s[k^1]=y;
	pushup(y);
	pushup(x);
}
void splay(int x,int k)
{
	while(tr[x].p!=k)
	{
		int y=tr[x].p,z=tr[y].p;
		if(z!=k)
		{
			if((tr[y].s[1]==x)^(tr[z].s[1]==y))
			rotate(x);
			else rotate(y);
		}
		rotate(x);
	}
	if(!k)
	root=x;
}
void insert(int v)
{
	int u=root,p=0;
	while(u)
	p=u,u=tr[u].s[v>tr[u].v];
	u=++idx;
	if(p)
	tr[p].s[v>tr[p].v]=u;
	tr[u].init(v,p);
	splay(u,0);
}
int get_k(int k) //得到第k大数的下标 
{
	int u=root;
	while(1)
	{
		pushdown(u);
		if(tr[tr[u].s[0]].size>=k)
		u=tr[u].s[0];
		else if(tr[tr[u].s[0]].size+1==k)
		return u;
		else k=k-tr[tr[u].s[0]].size-1,u=tr[u].s[1];
	}
	return -1;
}
int get() //得到目前序列最后的数的下标  
{
	int u=root;
	while(u)
	{
		pushdown(u);
		if(!tr[u].s[1])
		return u;
		u=tr[u].s[1];
	}
	return -1;
}
void output(int u)
{
	pushdown(u);
	if(tr[u].s[0])
	output(tr[u].s[0]);
	if(tr[u].v>=1&&tr[u].v<=n)
	printf("%d\n",tr[u].v);
	if(tr[u].s[1])
	output(tr[u].s[1]);
}
int build(int l,int r)
{
	
	int mid=(l+r)>>1;
	tr[mid].v=mid;
	if(l>r)
	return 0;
	tr[mid].s[0]=build(l,mid-1);
	tr[mid].s[1]=build(mid+1,r);
	tr[tr[mid].s[0]].p=mid;
	tr[tr[mid].s[1]].p=mid;
	pushup(mid);
	return mid;
}
int main()
{
//	freopen("2.txt","w",stdout);
	scanf("%d%d",&n,&m);
	root=build(1,n);
	while(m--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		int ls=get_k(l-1),rs=get_k(r+1);
		
		splay(ls,0);
		splay(rs,ls); //这两个splay可以将待修改区间转为rs的左子树 
		
		tr[tr[rs].s[0]].flag^=1;
		int rua=get();  
		tr[tr[rs].s[0]].p=rua;
		tr[rua].s[1]=tr[rs].s[0];
		pushup(rua);
		tr[rs].s[0]=0;
		
	}
	output(root);
	return 0;
}

正确性应该没问题,用过udebug测过 但T掉了

2021/6/26 20:59
加载中...