suxxsfe

一言(ヒトコト)

打印2

数据结构

普通堆、可删堆

struct Node{
	inline int operator < (const Node &o){}
	_inline int operator == (const Node &o){}
};
inline void swap(Node &a,Node &b){}
struct Heap{
	Node a[N];
	int size;
	inline void push(const Node &x){
		int i=++size,fa;a[size]=x;
		while(i>1){
			fa=i>>1;
			if(a[fa]<a[i]) return;
			swap(a[fa],a[i]);i=fa;
		}
	}
	inline void pop(){
		int i=1,ls,rs;a[1]=a[size--];
		while((i<<1)<=size){
			ls=i<<1;rs=ls|1;
			if(rs<=size&&a[rs]<a[ls]) ls=rs;
			if(a[i]<a[ls]) return;
			swap(a[ls],a[i]);i=ls;
		}
	}
};
struct DeletableHeap{
	Heap ins,dele;
	inline Node top(){while(dele.size&&ins.a[1]==dele.a[1]) ins.pop(),dele.pop();return ins.a[1];}
	inline void pop(){while(dele.size&&ins.a[1]==dele.a[1]) ins.pop(),dele.pop();ins.pop();}
	inline void push(const Node &x){ins.push(x);}
	inline void del(const Node &x){dele.push(x);}
	inline void clear(){ins.size=dele.size=0;}
	inline int size(){return ins.size-dele.size;}
	inline int empty(){return ins.size==dele.size;}
};

使用自定义函数重载 std::setstd::priority_queue 等的比较

inline int pqueCmp(const int &a,const int &b){return a>b;}
std::priority_queue<int,std::vector<int>,int(*)(const int &a,const int &b)>pque(pqueCmp);

树状数组

int tree[N];
#define lowbit(x) (x&(-x))
inline void add(int pos,int k){for(;pos<=n;pos+=lowbit(pos)) tree[pos]+=k;}
inline int ask(int pos){
	int ans=0;
	for(;pos;pos-=lowbit(pos)) ans+=tree[pos];
	return ans;
}

线段树合并、分裂

Node* merge(Node *a,Node *b,int l,int r){
	if(a==null) return b;
	if(b==null) return a;
	if(l==r) return a->cnt+=b->cnt,a;
	int mid=(l+r)>>1;
	a->ls=merge(a->ls,b->ls,l,mid);a->rs=merge(a->rs,b->rs,mid+1,r);
	pushup(a);return a;
}
void split(Node *&a,Node *&b,int l,int r,int ql,int qr){
	if(a==null) return;
	if(ql<=l&&r<=qr) return b=a,a=null,void();
	if(b==null) New(b);
	int mid=(l+r)>>1;
	if(ql<=mid) split(a->ls,b->ls,l,mid,ql,qr);
	if(qr>mid) split(a->rs,b->rs,mid+1,r,ql,qr);
	pushup(a);pushup(b);
}

替罪羊树

#define alpha 0.7
struct Node{
	Node *ls,*rs;
	int val,cnt,size;//size:num of not deleted,cnt:all
	int deleted;
	inline void pushup(){}
}*null,*root,*nodes[1100005],**badtag;
int nodeNum;
inline int isbad(Node *tree){return tree->ls->cnt>alpha*tree->cnt+5||tree->rs->cnt>alpha*tree->cnt+5;}
void dfs(Node *tree){
	if(tree==null) return;
	dfs(tree->ls);
	if(!tree->deleted) nodes[++nodeNum]=tree;
	dfs(tree->rs);
	if(tree->deleted) delete tree;
}
Node *build(int l,int r){
	if(l>r) return null;
	if(l==r){
		nodes[l]->ls=nodes[l]->rs=null;
		nodes[l]->cnt=nodes[l]->size=1;
		return nodes[l];
	}
	int mid=(l+r)>>1;
	Node *tree=nodes[mid];
	tree->ls=build(l,mid-1);tree->rs=build(mid+1,r);
	tree->pushup();
	return tree;
}
inline void rebuild(Node *&tree){
	nodeNum=0;
	dfs(tree);
	tree=build(1,nodeNum);
}
void insert(Node *&tree,int x){
	if(tree==null){
		tree=new Node;
		tree->ls=tree->rs=null;
		tree->deleted=0;tree->val=x;
		tree->size=tree->cnt=1;
		return;
	}
	tree->size++;tree->cnt++;
	if(x>tree->val) insert(tree->rs,x);
	else insert(tree->ls,x);
	if(isbad(tree)) badtag=&tree;
}
inline void Insert(Node *&tree,int x){
	badtag=&null;
	insert(tree,x);
	if(badtag!=&null) rebuild(*badtag);
}
inline int rank(Node *tree,int x){
	int ans=1;
	while(tree!=null){
		if(x<=tree->val) tree=tree->ls;
		else{
			ans+=tree->ls->size+!tree->deleted;
			tree=tree->rs;
		}
	}
	return ans;
}
inline int kth(tr *tree,int rk){
	while(tree!=null){
		if(!tree->deleted&&tree->ls->size+1==rk) return tree->val;
		if(rk<=tree->ls->size) tree=tree->ls;
		else{
			rk-=tree->ls->size+!tree->deleted;
			tree=tree->rs;
		}
	}
}
void erase(tr *tree,int rk){
	if(!tree->deleted&&rk==tree->ls->size+1){
		tree->deleted=1;
		tree->size--;
		return;
	}
	tree->size--;
	if(rk<=tree->ls->size+!tree->deleted) erase(tree->ls,rk);
	else erase(tree->rs,rk-tree->ls->size-!tree->deleted);
}

fhq-treap

struct Node{
	Node *ls,*rs;
	int val,rnd,size;
	inline void pushup(){size=1+ls->size+rs->size;}
}*root,*null;
inline void init(Node *x){x->ls=x->rs=null;x->size=1;x->rnd=rand();}
inline void init(){
	srand(822);
	null=new Node;null->ls=null->rs=null;null->size=0;null->val=INT_INF;
	root=null;
}
void split(Node *tree,int k,Node *&L,Node *&R){
	if(tree==null) return L=R=null,void();
	if(tree->ls->size>=k){
		R=tree;
		split(tree->ls,k,L,R->ls);
		R->pushup();
	}
	else{
		L=tree;
		split(tree->rs,k-tree->ls->size-1,L->rs,R);
		L->pushup();
	}
}
Node* merge(Node *L,Node *R){
	if(L==null) return R;
	if(R==null) return L;
	if(L->rnd<R->rnd){
		L->rs=merge(L->rs,R);
		return L->pushup(),L;
	}
	else{
		R->ls=merge(L,R->ls);
		return R->pushup(),R;
	}
}
inline int rank(int val){
	int ans=1;
	Node *tree=root;
	while(tree!=null){
		if(val<=tree->val) tree=tree->ls;
		else{
			ans+=tree->ls->size+1;
			tree=tree->rs;
		}
	}
	return ans;
}
inline void insert(int val){
	int rk=rank(val)-1;
	Node *x,*y;
	split(root,rk,x,y);
	Node *a=new Node;init(a);a->val=val;
	root=merge(merge(x,a),y);
}
inline void del(int val){
	int rk=rank(val);
	Node *x,*y,*z;
	split(root,rk,x,z);
	split(x,rk-1,x,y);//y->val=val,y->size=1
	root=merge(x,z);
	delete y;
}
inline int kth(int k){
	Node *x,*y,*z;
	split(root,k-1,x,y);
	split(y,1,y,z);
	root=merge(x,merge(y,z));
	return y->val;
}

link-cut-tree

struct LCT{
	struct Node{
		Node *son[2],*fa;
		int val,res;
		int tag;
	}addr_[N],*null,*addr;
	inline void init(){addr=addr_;null=addr;}
	#define ident(tree,fa) (fa->son[1]==tree)
	#define notroot(tree) (tree->fa->son[0]==tree||tree->fa->son[1]==tree)
	#define pushup(tree) (tree->res=tree->son[0]->res^tree->son[1]->res^tree->val)
	inline void connect(Node *tree,Node *fa,int k){fa->son[k]=tree;tree->fa=fa;}
	inline void pushdown(Node *tree){
		if(!tree->tag) return;
		tree->tag=0;
		tree->son[0]->tag^=1;tree->son[1]->tag^=1;
		std::swap(tree->son[0],tree->son[1]);
	}
	inline void rotate(Node *tree){
		Node *fa=tree->fa,*faa=fa->fa;
		pushdown(fa);pushdown(tree);
		int k=ident(tree,fa);
		connect(tree->son[k^1],fa,k);
		tree->fa=faa;
		if(notroot(fa)) faa->son[ident(fa,faa)]=tree;
		connect(fa,tree,k^1);
		pushup(fa);pushup(tree);
	}
	inline void splay(Node *tree){
		Node *fa=tree->fa,*faa=fa->fa;
		while(notroot(tree)){
			fa=tree->fa;faa=fa->fa;
			if(notroot(fa)) rotate((ident(tree,fa)^ident(fa,faa))?tree:fa);
			rotate(tree);
		}
	}
	inline void access(Node *x){
		for(Node *lastx=null;x!=null;lastx=x,x=x->fa){
			pushdown(x);splay(x);x->son[1]=lastx;pushup(x);
		}
	}
	inline void makeroot(Node *x){access(x);splay(x);x->tag^=1;}
	inline Node* findroot(Node *x){
		access(x);splay(x);pushdown(x);
		while(x->son[0]!=null) x=x->son[0],pushdown(x);
		splay(x);return x;
	}
	inline void link(Node *x,Node *y){makeroot(x);if(findroot(y)!=x) x->fa=y;}
	inline void cut(Node *x,Node *y){
		makeroot(x);
		if(findroot(y)!=x||y->fa!=x||y->son[0]!=null) return;
		y->fa=x->son[1]=null;pushup(x);
	}
	inline Node* split(Node *x,Node *y){makeroot(x);access(y);splay(y);return y;}
	inline Node* Split(int x,int y){return split(addr+x,addr+y);}
	inline void link(int x,int y){link(addr+x,addr+y);}
	inline void cut(int x,int y){cut(addr+x,addr+y);}
	inline void change(int o,int val){Node *x=addr+o;splay(x);x->val=val;pushup(x);}
};

树分块

void dfs(int u,int last=0){
	deep[u]=deep[fa[0][u]]+1;
	for(int j=1;j<=LOG_N;j++) fa[j][u]=fa[j-1][fa[j-1][u]];
	if(keyId[u]){
		lastKey[u]=last;
		int lastid=keyId[last];set[keyId[u]][lastid].resize(N);set[keyId[u]][lastid].reset();
		for(int i=u;i^last;i=fa[0][i]) set[keyId[u]][lastid].set(id[i],1);
		for(int i=lastKey[last];i;i=lastKey[i]){
			set[keyId[u]][keyId[i]].resize(N);
			set[keyId[u]][keyId[i]]=set[keyId[u]][lastid]|set[lastid][keyId[i]];
		}
		last=u;
	}
	for(int i=G.fir[u];i;i=G.nex[i])if(G.to[i]^fa[0][u]) fa[0][G.to[i]]=u,dfs(G.to[i],last);
}
inline int getLca(int u,int v){
	if(deep[u]<deep[v]) lib::swap(u,v);
	for(int j=LOG_N;~j;j--)if(deep[fa[j][u]]>=deep[v]) u=fa[j][u];
	if(u==v) return u;
	for(int j=LOG_N;~j;j--)if(fa[j][u]^fa[j][v]) u=fa[j][u],v=fa[j][v];
	return fa[0][u];
}
inline void pre(int n){
	static int oo[N];
	for(int i=1;i<=n;i++) oo[i]=i;
	srand(822);
	std::random_shuffle(oo+1,oo+1+n);
	for(int i=1,cntKey=0,o=lib::min(n,BN);i<=o;i++) keyId[oo[i]]=++cntKey;
	std::sort(oo+1,oo+1+n,[](const int &a,const int &b){return val[a]<val[b];});
	for(int o=0,i=1;i<=n;i++){
		if(val[oo[i]]!=val[oo[i-1]]||i==1) o++;
		id[oo[i]]=o;
	}
	dfs(1);
}
	while(m--){
		while(!keyId[u]&&(u^lca)) u=fa[0][u];
		while(!keyId[v]&&(v^lca)) v=fa[0][v];
		int blockId=keyId[u];
		while(deep[lastKey[u]]>=deep[lca]) u=lastKey[u];
		blockId=keyId[v];
		while(deep[lastKey[v]]>=deep[lca]) v=lastKey[v];
		while(u^lca) u=fa[0][u];
		while(v^lca) v=fa[0][v];
	}

bitset

struct Bitset{
#define W 63
	unsigned long long *a;
	int size;
	inline Bitset(){size=0;}
	inline ~Bitset(){if(size) delete []a;}
	inline void resize(const int &s){
		if(size) delete []a;
		size=(s+W)>>6;
		a=new unsigned long long[size];
	}
	inline void reset(){__builtin_memset(a,0,size*sizeof(a[0]));}
	inline void set(){__builtin_memset(a,255,size*sizeof(a[0]));}
	inline int operator [] (const int &pos)const{return (a[pos>>6]>>(pos&W))&1;}
	inline void operator = (const Bitset &o){resize(o.size<<6);__builtin_memcpy(a,o.a,size*sizeof(a[0]));}
	inline void set(const int &pos,const int &val){
        a[pos>>6]&=~(1ull<<(pos&W));a[pos>>6]|=((unsigned long long)val<<(pos&W));}
    }
	inline int count(){
		int ans=0;
		for(int i=0;i<size;i++) ans+=__builtin_popcountll(a[i]);
		return ans;
	}
	inline Bitset operator ^ (const Bitset &o)const{
		Bitset ans;ans=*this;
		for(int i=0;i<size;i++) ans.a[i]^=o.a[i];
		return ans;
	}
	inline Bitset operator | (const Bitset &o)const{
		Bitset ans;ans=*this;
		for(int i=0;i<size;i++) ans.a[i]|=o.a[i];
		return ans;
	}
	inline Bitset operator & (const Bitset &o)const{
		Bitset ans;ans=*this;
		for(int i=0;i<size;i++) ans.a[i]&=o.a[i];
		return ans;
	}
	inline void operator ^= (const Bitset &o){for(int i=0;i<size;i++) a[i]^=o.a[i];}
	inline void operator |= (const Bitset &o){for(int i=0;i<size;i++) a[i]|=o.a[i];}
	inline void operator &= (const Bitset &o){for(int i=0;i<size;i++) a[i]&=o.a[i];}
	inline Bitset operator ~ ()const{
		Bitset ans;ans=*this;
		for(int i=0;i<size;i++) ans.a[i]=~ans.a[i];
		return ans;
	}
	inline Bitset operator >> (int bit){
		Bitset ans;ans=*this;
		int o=bit>>6;bit&=W;
		if(o) for(int i=0;i+o<size;i++) ans.a[i]=a[i+o];
		for(int i=size-o;i<size;i++) ans.a[i]=0;
		if(!bit) return ans;
		int S=(1ull<<bit)-1;
		for(int i=0;i<size-1;i++) ans.a[i]>>=bit,ans.a[i]|=(ans.a[i+1]&S)<<(W+1-bit);
		ans.a[size-1]>>=bit;
		return ans;
	}
#undef W
};

双模哈希

#define HASH_MOD1 1000000007
#define HASH_MOD2 1000000009
#define HASH_BASE 822
struct Hash{
	unsigned long long a,b;
	inline void operator = (const unsigned long long &o){a=b=o;}
	inline Hash operator + (const Hash &o){return (Hash){(a+o.a)%HASH_MOD1,(b+o.b)%HASH_MOD2};}
	inline Hash operator - (const Hash &o){return (Hash){(a-o.a+HASH_MOD1)%HASH_MOD1,(b-o.b+HASH_MOD2)%HASH_MOD2};}
	inline Hash operator * (const unsigned long long &o){return (Hash){a*o%HASH_MOD1,b*o%HASH_MOD2};}
	inline int operator == (const Hash &o){return a==o.a&&b==o.b;}
	inline int operator != (const Hash &o){return a!=o.a||b!=o.b;}
	inline int operator < (const Hash &o)const{return a==o.a?b<o.b:a<o.a;}
	inline unsigned __int128 toUint128(){return (unsigned __int128)a*_ULL_MAX+b;}
};
posted @ 2023-09-03 19:23  suxxsfe  阅读(16)  评论(0编辑  收藏  举报