给Splay做此题全部TLE的人一些提示
  • 板块P1188 PASTE
  • 楼主y_kx_b
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/4/20 23:35
  • 上次更新2023/10/28 03:13:16
查看原帖
给Splay做此题全部TLE的人一些提示
592895
y_kx_b楼主2022/4/20 23:35

粘贴完了记得加fa[paster]=next

example(滑到最底端食用)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define gc getchar
#define debug
#undef debug
using namespace std;
int read()
{
    int x=0;
    bool fh=1;
    char ch=gc();
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')fh=0;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
        x=(x<<1)+(x<<3)+(ch^48),ch=gc();
    return fh?x:-x;
}
const int _=0,N=114514;
/**
 *  N:??,?????
 *  ch[N][2]:????,ch[x][0]??x????,ch[x][1]??x?????
 *  val[N]:????,val[x]??x?????
 *  cnt[N]:????,cnt[x]??x???????????
 *  par[N]:????,par[x]??x?????
 *  size[N]:????,size[x]??x??????????(??????)?
 */
namespace SPLAY//https://www.shuzhiduo.com/A/xl56emaxJr/
{
    int ch[N][2],val[N],cnt[N],par[N],size[N],root=0,tot=0;
    int n;
    #define fa par
    inline bool check(int x){return ch[par[x]][1]==x;}
    inline void pushup(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];}
    #define revolve spin 
    #define rotate revolve
    void spin(int x)
    {
        int y=par[x],z=par[y],k=check(x),w=ch[x][k^1];
        ch[y][k]=w,par[w]=y;
        ch[z][check(y)]=x,par[x]=z;
        ch[x][k^1]=y,par[y]=x;
        pushup(y),pushup(x);
    }
    void splay(int x,int goal=0)
    {
        while(par[x]!=goal)
        {
            int y=par[x];
            if(par[y]!=goal)
            {
                if(check(y)==check(x))spin(y);
                else revolve(x);
            }
            rotate(x);
        }
        if(!goal)root=x;
    }
    void find(int x)
    {
        if(!root)return;
        int cur=root;
        while(ch[cur][x>val[cur]]&&val[cur]!=x)
            cur=ch[cur][x>val[cur]];
        splay(cur);
    }
    void insert(int x)
    {
        int cur=root,p=0;
        while(cur&&val[cur]!=x)
        {
            p=cur;
            cur=ch[cur][x>val[cur]];
        }
        if(cur)//val[cur]==x
            cnt[cur]++;
        else
        {
            cur=++tot;//tot!=0
            if(p)ch[p][x>val[p]]=cur;
            ch[cur][0]=ch[cur][1]=0;
            val[cur]=x,par[cur]=p,cnt[cur]=size[cur]=1;
        }
        splay(cur);
    }
    inline int rnk(int x)
    {
        find(x);
        return size[ch[root][0]]+1;
    }
    int kth(int k)
    {
        int cur=root;
        while(1)
        {
            if(ch[cur][0]&&k<=size[ch[cur][0]])
                cur=ch[cur][0];
            else if(k>size[ch[cur][0]]+cnt[cur])
            {
                k-=size[ch[cur][0]]+cnt[cur];
                cur=ch[cur][1];
            }
            else return cur;
        }
    }
    int pre(int x)
    {
        find(x);
        if(val[root]<x)return root;
        int cur=ch[root][0];
        while(ch[cur][1])cur=ch[cur][1];
        return cur;
    }
    int suc(int x)
    {
        find(x);
        if(val[root]>x)return root;
        int cur=ch[root][1];
        while(ch[cur][0])cur=ch[cur][0];
        return cur;
    }
    void remove(int x)
    {
        int last=pre(x),next=suc(x);
        splay(last),splay(next,last);
        int tar=ch[next][0];
        if(val[tar]!=x)puts("UKE");
        if(cnt[tar]>1)
             cnt[tar]--,
             pushup(tar),
             splay(tar);
        else ch[next][0]=0,
             size[next]--,size[last]--;
    }
    void __main()
    {
        insert(0xcfcfcfcf);//-808464433
        insert(0x3f3f3f3f);
        size[1]=size[2]=cnt[1]=cnt[2]=0;
        int p=read();
        while(p--)
        {
            int op=read(),x=read();
            switch(op)
            {
                case 1:insert(x);break;
                case 2:remove(x);break;
                case 3:printf("%d\n",rnk(x));break;
                case 4:printf("%d\n",val[kth(x)]);break;
                case 5:printf("%d\n",val[pre(x)]);break;
                case 6:printf("%d\n",val[suc(x)]);break;
            }
        }
    }
    int _pre(int x)
    {
    	splay(x);
    	if(!ch[x][0])return fa[x];
    	x=ch[x][0];
    	while(ch[x][1])x=ch[x][1];
    	return x;
    }
    int _suc(int x)
    {
    	splay(x);
    	if(!ch[x][1])return fa[x];
    	x=ch[x][1];
    	while(ch[x][0])x=ch[x][0];
    	return x;
    }
    void _insert(int x)
    {
    	int cur=root,p=0;
        while(cur&&cur!=x)
        {
            p=cur;
            cur=ch[cur][x>cur];
        }
        cur=++tot;//tot!=0
        if(p)ch[p][x>p]=cur;
        ch[cur][0]=ch[cur][1]=0;
        val[cur]=x,par[cur]=p,cnt[cur]=size[cur]=1;
        splay(cur);
    }
    void init()
    {
    	_insert(1);
//        size[1]=size[2]=cnt[1]=cnt[2]=0;
        for(int i=1;i<=n;i++)
        	_insert(i+1);
        _insert(n+2);
    }
    void output(int k)
    {
//    	for(int i=2;i<=k+1;i++)
//    		printf("%d\n",val[kth(i)]-1);
		int cur=kth(1);
		while(k--)
			printf("%d\n",val[cur=_suc(cur)]-1);
    }
    void main()
    {
    	n=read();
    	init();
    	int q=read();
    	while(q--)
    	{
    		int a=read(),b=read(),c=read();
    		int last=kth(a),next=kth(b+2);
    		splay(last);splay(next,last);
    		int paster=ch[next][0];ch[next][0]=0;
    		pushup(next),pushup(last);
//    		last=kth(c+1),next=kth(c+2);
			last=kth(c+1),next=_suc(last);
			#ifdef debug
			if(next!=kth(c+2))
				puts("_1\nUKE");
			#endif
    		splay(last);splay(next,last);
			#ifdef debug
    		if(ch[next][0])
    			printf("%dUKE\n",ch[next][0]);
    		#endif
    		ch[next][0]=paster;
    		fa[paster]=next;//important!!!
    		pushup(next),pushup(last);
    	}
    	output(10);
    }
}
int main(){SPLAY::main();return~~(0^_^0);}
2022/4/20 23:35
加载中...