萌新刚学 Splay 求助优化卡常
查看原帖
萌新刚学 Splay 求助优化卡常
414386
Isshiki·Iroha楼主2021/10/11 19:38
/*
	Name: 普通平衡树
	Copyright: 深基16.例7
	Author: Isshiki Iroha
	Date: 011/10/21 8:50
	Description: Splay
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
namespace Mashiro {
	char buf[1<<18],*p1=buf,*p2=buf;
	inline int getc() {
		return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<18,stdin),p1==p2)?EOF:*p1++;
	}
#ifndef ONLINE_JUDGE
#define getc() getchar()
#endif
	template<typename T>inline void read(T& x) {
		x=0;
		int f=1;
		char ch=getc();
		while(!isdigit(ch)) {
			if(ch=='-')f=~f+1;
			ch=getc();
		}
		while (isdigit (ch)) {
			x=(x<<3)+(x<<1)+(ch^48);
			ch=getc();
		}
		x*=f;
	}
	template <typename T,typename... Args> inline void read(T& x, Args&... args) {
		read(x);
		read(args...);
	}
	char buffer[1<<18];
	int p11=-1;
	const int p22=(1<<18)-1;
	inline void flush() {
		fwrite(buffer,1,p11+1,stdout),p11=-1;
	}
	inline void putc(const char &x) {
		if (p11==p22) flush();
		buffer[++p11]=x;
	}
	template<typename T>inline void write(T x) {
		static int buf[40],top=0;
		if(x<0)putc('-'),x=~x+1;
		while(x)buf[++top]=x%10,x/=10;
		if(top==0)buf[++top]=0;
		while (top) putc(buf[top--]^48);
		putc(' ');
		flush();
	}
	template <typename T,typename... Args> inline void write(T x, Args... args) {
		write(x);
		write(args...);
	}
}
using namespace Mashiro;
const int maxn=1e6+10;
const int PreNotFound=-2147483647;
const int NextNotFound=2147483647;
int n,m;
struct Pair{
    int first,second;
    Pair(int F=1,int S=1):first(F),second(S){}
    bool operator <(const Pair &A)const{
        if(first==A.first)return second<A.second;
        return first<A.first;
    }
    bool operator ==(const Pair &A)const {
        return (first==A.first&&second==A.second);
    }
};
#define debug printf("\n----------\n")
struct Splay {
	int Root=0,tot=0;
	//根编号,结点个数
	struct node {
		int son[2];//儿子编号,0 - 左儿子;1 - 右儿子
		int sizes;//子树大小
		int fa;//父亲的编号
		Pair val;//权值
		int cnt;//这个权值出现的次数
	} tree[maxn];
#define ls(u) tree[u].son[0]
#define rs(u) tree[u].son[1]
#define sizes(u) tree[u].sizes
#define cnt(u) tree[u].cnt
#define fa(u) tree[u].fa
#define val(u) tree[u].val
#define Son(u,x) tree[u].son[x]
	inline void maintain(int u) {
		sizes(u)=sizes(ls(u))+sizes(rs(u))+cnt(u);
	}
	inline void clear(int u) {
		ls(u)=rs(u)=cnt(u)=val(u).first=val(u).second=fa(u)=sizes(u)=0;
	}
	inline int check(int u) {
		return rs(fa(u))==u;
	}
	inline void rotate(int u) {
		int u_fa=fa(u),u_fa_fa=fa(u_fa);
		int son_check=check(u);
		Son(u_fa,son_check)=Son(u,son_check^1);
		if(Son(u,son_check^1))fa(Son(u,son_check^1))=u_fa;
		Son(u,son_check^1)=u_fa;
		fa(u_fa)=u;
		fa(u)=u_fa_fa;
		if(u_fa_fa)Son(u_fa_fa,u_fa==Son(u_fa_fa,1))=u;
		maintain(u);
		maintain(u_fa);
	}
	inline void splay(int u) {
		for(int f=fa(u); f=fa(u),f; rotate(u)) {
			if(fa(f))rotate(check(f)==check(u)?f:u);
		}
		Root=u;
	}
	inline void insert(Pair val) {
		if(!Root) {
			++tot;
			++cnt(tot);
			val(tot)=val;
			fa(tot)=0;
			Root=tot;
			maintain(tot);
			return;
		}
		int u=Root,fa=0;
		while(1) {
			if(val==val(u)) {
				++cnt(u);
				maintain(u);
				maintain(fa);
				splay(u);
				return;
			}
			fa=u;
			u=Son(u,val(u)<val);
			if(!u) {
				++tot;
				val(tot)=val;
				++cnt(tot);
				fa(tot)=fa;
				Son(fa,val(fa)<val)=tot;
				maintain(tot);
				maintain(fa);
				splay(tot);
				return;
			}
		}
	}
	inline int Rank(Pair val) {
		int ans=0,u=Root;
		while(u) {
			if(val<val(u)) {
				u=ls(u);
			} else {
				ans+=sizes(ls(u));
				if(val==val(u)) {
					splay(u);
					return ans+1;
				}
				ans+=cnt(u);
				u=rs(u);
			}
		}
		return ans+1;
	}
	inline int Pre() {
		int u=Son(Root,0);
		if(!u)return u;
		while(rs(u))u=rs(u);
		splay(u);
		return u;
	}
	inline void Delete(Pair val) {
		int sbwy=Rank(val);
		int u=Root;
		if(cnt(u)>1) {
			--cnt(u);
			maintain(u);
			return;
		}
		if(!ls(u)&&!rs(u)) {
			clear(u);
			Root=0;
			return;
		}
		if(!ls(u)) {
			Root=rs(u);
			fa(Root)=0;
			clear(u);
			return;
		}
		if(!rs(u)) {
			Root=ls(u);
			fa(Root)=0;
			clear(u);
			return;
		}
		int Prefix=Pre();
		Son(Prefix,1)=rs(u);
		fa(rs(u))=Prefix;
		clear(u);
		maintain(Root);
	}
} Tree;
unsigned int seed,last=7;
inline unsigned int Rand(unsigned int& seed,unsigned int last,const int m) {
	seed=seed*17+last;
	return seed%m+1;
}
int T;
int accepted[maxn];
int Times[maxn];
int main() {
	read(T);
	++T;
	while(--T) {
		read(m,n,seed);
		for(int i(0);i<=Tree.tot;++i){
			Tree.clear(i);
		}
        memset(accepted,0,sizeof accepted);
        memset(Times,0,sizeof Times);
        Tree.Root=Tree.tot=0;
		Tree.insert(Pair(-NextNotFound,NextNotFound));
		Tree.insert(Pair(NextNotFound,-NextNotFound));
		for(int i(1),person,times; i<=n; ++i) {
			person=Rand(seed,last,m);
			times=Rand(seed,last,m);
			//write(person,times);
			//putc('\n');
			if(accepted[person])Tree.Delete(Pair(accepted[person],-Times[person]));
            ++accepted[person];Times[person]+=times;
            Tree.insert(Pair(accepted[person],-Times[person]));
            last=Tree.tree[Tree.tree[Tree.Root].son[1]].sizes-1;
            write(last);
			putc('\n');
		}
	}
	return 0;
}
2021/10/11 19:38
加载中...