splay求调+疑问
  • 板块P2073 送花
  • 楼主12wty29
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/8/22 22:05
  • 上次更新2023/11/3 01:52:34
查看原帖
splay求调+疑问
251143
12wty29楼主2023/8/22 22:05

正常写splay都会插入最大最小值,那么本题是否存在方法利用二叉搜索树的性质,采用一直找左/右儿子的策略,用跳过该点的方式直接删除?如果不行那么原因是什么?

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#include<ctime>
//#include<bits/stdc++.h>
#define chp(x) (t[t[x].fa].ch[1]==x)
#define int long long
#define M 1000001
//#define inf 2147483647
using namespace std;
typedef int it;

inline it read()
{
  int f=0,fu=1;
  char c=getchar();
  while(c<'0' || c>'9') 
  {
    if(c=='-') fu=-1; c=getchar();
  }
  while(c>='0' && c<='9') {f=(f<<1)+(f<<3)+(c-'0'); c=getchar();}
  return f*fu;
}
int n,m;
struct tree
{
  int ch[2];
  int w,c,fa;
}t[M];
int rt,tot,tmp;

inline void rotate(int x)
{
  int y=t[x].fa,z=t[y].fa;
  int p1=chp(x);
  t[y].ch[p1]=t[x].ch[!p1];
  t[t[x].ch[!p1]].fa=y;
  if(z) t[z].ch[chp(y)]=x;
  t[x].fa=z;
  t[x].ch[!p1]=y;t[y].fa=x;
}

inline void splay(int x,int goal)
{
  while(t[x].fa!=goal)
  {
    int y=t[x].fa,z=t[y].fa;
	if(z)
	  if(chp(x)^chp(y)) rotate(x);
	  else rotate(y);
	rotate(x);
  }
  if(goal==0) rt=x;
}

inline void insert(int x,int y)
{
  int u=rt,nf=0;
  while(u && t[u].w!=y)
  {
    nf=u;
	u=t[u].ch[t[u].c<y];
  }
  if(u) return ;
  else
  {
    u=++tot;
	tmp++;
	t[u].fa=nf;
	if(nf) t[nf].ch[t[nf].c<y]=u;
	t[u].w=x;
	t[u].c=y;
  }
  splay(u,0);
}

inline void remote(int p)
{
  if(tmp==0) return;
  tmp--;
  int u=rt;
  while(t[u].ch[p])
    u=t[u].ch[p];
  t[t[u].fa].ch[p]=t[u].ch[!p];
  t[t[u].ch[!p]].fa=t[u].fa;
  t[u].fa=0;
}
queue<int>sp;
inline void outp()
{
  int answ=0,ansc=0;
  sp.push(rt);
  while(!sp.empty())
  {
    int k=sp.front();
	sp.pop();
	answ+=t[k].w;
	ansc+=t[k].c;
	if(t[k].ch[1]) sp.push(t[k].ch[1]);
	if(t[k].ch[0]) sp.push(t[k].ch[0]);
  }
  cout<<answ<<" "<<ansc;
}

signed main()
{
    //freopen("P2073.in","r",stdin);
    //freopen("P2073.out","w",stdout);
	int op;
	//insert(0,-inf);
	//insert(0,inf);
	while(1)
	{
	  op=read();
	  if(op==-1) break;
	  if(op==1)
	  {
	    int x=read(),y=read();
		insert(x,y);
	  }
	  if(op==2)
	    remote(1);
	  if(op==3)
	    remote(0);
	}
	outp();
    return 0;
}

2023/8/22 22:05
加载中...