这题Splay需要优化常数吗?T了4个点求助
查看原帖
这题Splay需要优化常数吗?T了4个点求助
592895
y_kx_b楼主2022/7/21 20:48
#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<string>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define gc std::getchar
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;}
#define mem0(s) memset(s,0,sizeof s)
#define mem0x3f(s) memset(s,0x3f,sizeof s)
#define mem0xff(s) memset(s,0xff,sizeof s)
#define itn int
#define x first
#define y second
#if 0
#define int long long
#endif
using namespace std;
typedef pair<int,int>PII;
const int _=0,N=1919810;
namespace SPLAY//https://www.shuzhiduo.com/A/xl56emaxJr/
{
    int cnt[N],size[N],ch[N][2],val[N],fa[N],root=0,idx1=0;
    inline bool check(int x){return ch[fa[x]][1]==x;}
    inline void pushup(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+cnt[x];}
    #define rotate spin
    #define chk check
    void spin(int x)
    {
    	itn y=fa[x],z=fa[y],k=chk(x),w=ch[x][k^1];
    	ch[z][chk(y)]=x,fa[x]=z;
    	ch[y][k]=w,fa[w]=y;
    	ch[x][k^1]=y,fa[y]=x;
    	pushup(y),pushup(x);
    }
    void splay(int x,int goal=0)
    {
    	int y=fa[x];
    	while(y!=goal){
    		if(fa[y]!=goal)chk(x)^chk(y)?/*不在一条链上*/rotate(x):rotate(y);
			spin(x);
			y=fa[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=root;
    	while(val[cur]!=x&&cur)
    		p=cur,cur=ch[cur][x>val[cur]];
		if(val[cur]==x)
			cnt[cur]++;
		else{
			cur=++idx1;
			if(p)ch[p][x>val[p]]=cur;
			ch[cur][0]=ch[cur][1]=0;
			size[cur]=cnt[cur]=1;
			val[cur]=x;fa[cur]=p;
		}
		splay(cur);
    }
    inline int rnk(int x)
    {
    	find(x);
    	return size[ch[root][0]]+1+(val[root]<x?cnt[root]:0);
    }
    int kth(int k)
    {
    	itn 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],p=root;
    	while(cur)
    		p=cur,cur=ch[cur][1];
    	return p;
    }
    int suc(int x)
    {
    	find(x);
    	if(val[root]>x)return root;
    	int cur=ch[root][1],p=root;
    	while(cur)
    		p=cur,cur=ch[cur][0];
    	return p;
    }
    void remove(int x)
    {
    	int last=pre(x),next=suc(x);
    	splay(last),splay(next,last);
    	int tar=ch[next][0];
    	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;
            }
        }
    }
    void P6136_main()
    {
    	insert(0xffffffff),insert(0x7fffffff),size[1]=size[2]=cnt[1]=cnt[2]=0;
    	int n=read(),m=read(),last=0,ans=0;
    	while(n--)insert(read());
    	while(m--){
    		int op=read(),x=read()^last;
    		switch(op){
    			case 1:insert(x);break;
    			case 2:remove(x);break;
    			case 3:last=rnk(x);ans^=last;break;
    			case 4:last=val[kth(x)];ans^=last;break;
    			case 5:last=val[pre(x)];ans^=last;break;
    			case 6:last=val[suc(x)];ans^=last;break;
			}
		}
		printf("%d\n",ans);
    }
}
int main(){SPLAY::P6136_main();return~~(0^_^0);}
2022/7/21 20:48
加载中...