suxxsfe

一言(ヒトコト)

模板库-数据结构

数据结构

普通堆、可删堆

struct Node{
	__attribute__((always_inline))inline int operator < (const Node &o){}
	__attribute__((always_inline))inline int operator == (const Node &o){}
};
__attribute__((always_inline))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();}
	__attribute__((always_inline))inline void push(const Node &x){ins.push(x);}
	__attribute__((always_inline))inline void del(const Node &x){dele.push(x);}
	__attribute__((always_inline))inline void clear(){ins.size=dele.size=0;}
	__attribute__((always_inline))inline int size(){return ins.size-dele.size;}
	__attribute__((always_inline))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);

lambda 函数

auto pqueCmp=[](const int &a,const int &b){return a>b;};
std::priority_queue<int,std::vector<int>,decltype(pqueCmp)>pque(pqueCmp);

这样写有时候莫名奇妙的 RE???

并查集

int fa[N];
int find(int k){return fa[k]==k?k:fa[k]=find(fa[k]);}
inline void link(int x,int y){
	x=find(x);y=find(y);
	if(x!=y) fa[x]=y;
}

树状数组

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;
}

线段树

struct Node{
	Node *ls,*rs;
	int tag;
	inline void pushup(){}
	inline void pushdown(){}
}dizhi[N*2],*root=&dizhi[0];int tot=0;
void build(Node *&tree,int l,int r){
	tree=&dizhi[++tot];
	if(l==r) return;
	int mid=(l+r)>>1;
	build(tree->ls,l,mid);build(tree->rs,mid+1,r);
	tree->pushup();
}
void change(Node *tree,int l,int r,int pos){
	if(l==r) return;
	tree->pushdown();
	int mid=(l+r)>>1;
	pos<=mid?change(tree->ls,l,mid,pos):change(tree->rs,mid+1,r,pos);
	tree->pushup();
}
void change(Node *tree,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr) return;
	tree->pushdown();
	int mid=(l+r)>>1;
	if(ql<=mid) change(tree->ls,l,mid,ql,qr,k);
	if(qr>mid) change(tree->rs,mid+1,r,ql,qr,k);
	tree->pushup();
}
Data ask(Node *tree,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr) return tree->x;
	tree->pushdown();
	int mid=(l+r)>>1;
	if(qr<=mid) return ask(tree->ls,l,mid,ql,qr);
	if(ql>mid) return ask(tree->rs,mid+1,r,ql,qr);
	return ask(tree->ls,l,mid,ql,qr)+ask(tree->rs,mid+1,r,ql,qr);
}

简单平衡树

std::set

替罪羊树

#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;
	}dizhi[N],*null;
	inline void init(){null=&dizhi[0];}
	#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(&dizhi[x],&dizhi[y]);}
	inline void Link(int x,int y){link(&dizhi[x],&dizhi[y]);}
	inline void Cut(int x,int y){cut(&dizhi[x],&dizhi[y]);}
	inline void Change(int o,int val){Node *x=&dizhi[o];splay(x);x->val=val;pushup(x);}
};

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 @ 2022-03-09 21:28  suxxsfe  阅读(64)  评论(0编辑  收藏  举报