zoukankan      html  css  js  c++  java
  • 【题解】Luogu P1503 鬼子进村

    平衡树好题

    原题传送门

    这道题要用Splay,我博客里有对Splay的详细介绍

    这道题思维有点难,要把被摧毁的节点插入平衡树,而不是把没有摧毁的节点插入

    先把0和n+1插入平衡树,作为边界

    操作1:摧毁节点,把该点插入平衡树

    操作2:修复最后一个被摧毁节点的位置的可以用栈来求出,并把该点位置从平衡树中删除

    操作三:搞一个vis数组,记录是否被摧毁,如果被摧毁了,直接输出0,没被摧毁的话,输出该点后继的位置-该点前驱的位置-1,这应该也很好理解qaq

    剩下就没什么问题了(除了代码有点长)

    #pragma GCC optimize("O3")
    #include <bits/stdc++.h>
    #define root tree[0].ch[1]
    #define inf 1000000005
    using namespace std;
    inline int read()
    {
    	register int x=0,f=1;register 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-'0',ch=getchar();
    	return x*f;
    }
    inline void write(register int x)
    {
    	if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    	static int sta[36];int cnt=0;
    	while(x)sta[cnt++]=x%10,x/=10;
    	while(cnt)putchar(sta[--cnt]+48);
    }
    inline int Min(register int a,register int b)
    {
    	return a<b?a:b;
    }
    inline int Max(register int a,register int b)
    {
    	return a>b?a:b;
    }
    struct Splay{
    	int fa,ch[2],v,sum,rec;
    }tree[50005];
    int tot=0;
    inline bool findd(register int x)
    {
    	return x==tree[tree[x].fa].ch[0]?0:1;
    }
    inline void connect(register int x,register int fa,register int son)
    {
    	tree[x].fa=fa;
    	tree[fa].ch[son]=x;
    }
    inline void update(register int x)
    {
    	tree[x].sum=tree[tree[x].ch[0]].sum+tree[tree[x].ch[1]].sum+tree[x].rec;
    }
    inline void rotate(register int x)
    {
    	int Y=tree[x].fa;
    	int R=tree[Y].fa;
    	int Yson=findd(x);
    	int Rson=findd(Y);
    	int B=tree[x].ch[Yson^1];
    	connect(B,Y,Yson);
    	connect(Y,x,Yson^1);
    	connect(x,R,Rson);
    	update(Y),update(x);
    }
    inline void splay(register int x,register int to)
    {
    	to=tree[to].fa;
    	while(tree[x].fa!=to)
    	{
    		int y=tree[x].fa;
    		if(tree[y].fa==to)
    			rotate(x);
    		else if(findd(x)==findd(y))
    			rotate(y),rotate(x);
    		else
    			rotate(x),rotate(x);
    	}
    }
    inline int newpoint(register int v,register int fa)
    {
    	tree[++tot].v=v;
    	tree[tot].fa=fa;
    	tree[tot].sum=tree[tot].rec=1;
    	return tot;
    }
    inline void Insert(register int x)
    {
    	int now=root;
    	if(root==0)
    	{
    		newpoint(x,0);
    		root=tot;
    	}
    	else
    	{
    		while(19260817)
    		{
    			++tree[now].sum;
    			if(x==tree[now].v)
    			{
    				++tree[now].rec;
    				splay(now,root);
    				return;
    			}
    			int nxt=x<tree[now].v?0:1;
    			if(!tree[now].ch[nxt])
    			{
    				int p=newpoint(x,now);
    				tree[now].ch[nxt]=p;
    				splay(p,root);
    				return;
    			}
    			now=tree[now].ch[nxt];
    		}
    	}
    }
    inline int find(register int x)
    {
    	int now=root;
    	while(19260817)
    	{
    		if(x==tree[now].v)
    		{
    			splay(now,root);
    			return now;
    		}
    		int nxt=x<tree[now].v?0:1;
    		if(!tree[now].ch[nxt])
    			return 0;
    		now=tree[now].ch[nxt];
    	}
    }
    inline void delet(register int x)
    {
    	int pos=find(x);
    	if(!pos)
    		return;
    	if(tree[pos].rec>1)
    	{
    		--tree[pos].rec;
    		--tree[pos].sum;
    	}
    	else
    	{
    		if(!tree[pos].ch[0]&&!tree[pos].ch[1])
    			root=0;
    		else if(!tree[pos].ch[0])
    		{
    			root=tree[pos].ch[1];
    			tree[root].fa=0;
    		}
    		else
    		{
    			int left=tree[pos].ch[0];
    			while(tree[left].ch[1])
    				left=tree[left].ch[1];
    			splay(left,tree[pos].ch[0]);
    			connect(tree[pos].ch[1],left,1);
    			connect(left,0,1);
    			update(left);
    		}
    	}
    }
    inline int lower(register int v)
    {
    	int now=root,ans=-inf;
    	while(now)
    	{
    		if(tree[now].v<v&&tree[now].v>ans)
    			ans=tree[now].v;
    		if(tree[now].v>v)
    			now=tree[now].ch[0];
    		else
    			now=tree[now].ch[1];
    	}
    	return ans;
    }
    inline int upper(register int v)
    {
    	int now=root,ans=inf;
    	while(now)
    	{
    		if(tree[now].v>v&&tree[now].v<ans)
    			ans=tree[now].v;
    		if(tree[now].v>v)
    			now=tree[now].ch[0];
    		else
    			now=tree[now].ch[1];
    	}
    	return ans;
    }
    bool vis[50005];
    int stac[50005],top=-1;
    int main()
    {
    	memset(vis,false,sizeof(vis));
    	int n=read(),m=read();
    	Insert(0);
    	Insert(n+1);
    	while(m--)
    	{
    		char ch=getchar();
    		while(ch!='D'&&ch!='R'&&ch!='Q')
    			ch=getchar();
    		if(ch=='D')
    		{
    			int x=read();
    			vis[x]=true;
    			stac[++top]=x;
    			Insert(x);
    		}
    		else if(ch=='R')
    		{
    			vis[stac[top]]=false;
    			delet(stac[top--]);
    		}
    		else
    		{
    			int x=read();
    			if(vis[x])
    				puts("0");
    			else
    			{
    				write(upper(x)-lower(x)-1);
    				printf("
    ");
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    30天自制操作系统 学习笔记3
    30天自制操作系统 学习笔记1
    vmware+ubuntu配置笔记
    基于Spring Boot的问答系统之一:elasticsearch 7.2的hello world入门
    Asp.Net导出GridView数据到Excel
    ppt一键删除备注宏
    <a>的href=“#”和href="javascript:void(0)"
    Java增、删、改、查txt文件
    自定义窗体标题栏
    C#随机获得字符串组成帐号和密码并插入到数据库,将插入成功的数据计入文本
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/9960345.html
Copyright © 2011-2022 走看看