• 模板库数据结构


    数据结构

    普通堆、可删堆

    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;}
    };
    
  • 相关阅读:
    SP3946 MKTHNUM
    P1948 [USACO08JAN]电话线Telephone Lines(二分答案+最短路)
    CF375D Tree and Queries(dsu on tree)
    P2051 [AHOI2009]中国象棋(动态规划)
    P3810 【模板】三维偏序(陌上花开)(cdq分治)
    P4390 [BOI2007]Mokia 摩基亚(cdq分治)
    P2163 [SHOI2007]园丁的烦恼(cdq分治)
    UVA11270 Tiling Dominoes(轮廓线动态规划)
    P2475 [SCOI2008]斜堆(递归模拟)
    P2617 Dynamic Rankings(带修主席树)
  • 原文地址:https://www.cnblogs.com/suxxsfe/p/15987128.html
Copyright © 2020-2023  润新知