• CSP前算法模板复习


    强联通分量模板

    void tarjan(int x){
        dfn[x]=low[x]=++Time;
        stk[++top]=x;
        for(int i=head[x];~i;i=e[i].nxt){
            int v=e[i].v;
            if(!dfn[v]){
                tarjan(v);
                chkmin(low[x],low[v]);
            }
            else if(!color[v])chkmin(low[x],dfn[v]);        
        }
        if(low[x]==dfn[x]){
            ++color_cnt;
            do color[stk[top]]=color_cnt;while(top&&stk[top--]!=x);
        }
    }
    

    割点模板

    void tarjan(int x,int rt){
        int cnt=0;
        dfn[x]=low[x]=++Time;
        for(int i=head[x];~i;i=e[i].nxt){
            int v=e[i].v;
            if(!dfn[v]){
                fa[v]=x;
                tarjan(v,rt);
                chkmin(low[x],low[v]);
                if(low[v]>=dfn[x]&&u!=rt)cut[x]=1;
                if(x==rt)++cnt;
            }
            else if(fa[x]!=v) chkmin(low[x],dfn[v]);
        }
        if(x==rt&&cnt>=2)cut[x]=1;
    }
    

    割边模板

    void tarjan(int x,int fa){
        dfn[x]=low[x]=++Time;
        for(int i=head[x];~i;i=e[i].nxt){
            int v=e[i].v;
            if(!dfn[v]){
                tarjan(v,x);
                chkmin(low[x],low[v]);
                if(low[v]>dfn[x])cut[i]=1;
            }
            else if(v!=fa)chkmin(low[x],dfn[v]);
        }
    }
    

    最小生成树:Kruskal算法

    inline void Kruskal(){
        sort(e+1,e+m+1);
        int cnt=0,ans=0;
        for(int i=1;i<=m;++i)
        {
            int u=find(e[i].u),v=find(e[i].v),w=e[i].w;
            if(u!=v)
            {
                fa[u]=v;
                ans+=w;
    	        ++cnt;
            }
            if(cnt==n-1)break;
    	}
    }
    

    堆优化Prim算法

    typedef pair<int,int> pii;
    priority_queue<pii,vector<pii>,greater<pii> >pq;
    inline void Prim()
    {
        int cnt=0,ans=0;
       	memset(dis,127,sizeof dis);
        while(!pq.empty())
        {
            pii now=pq.top();pq.pop();
            if(vis[now.second])continue;
            vis[now.second]=1;
            ans+=now.first;
            for(int i=head[now.first];~i;i=e[i].nxt){
                int v=e[i].v;
                if(e[i].w<dis[v])
                    dis[v]=e[i].w,pq.push(pii(dis[v],v));
            }
            ++cnt;
            if(cnt==n-1)break;
        }
    }
    

    01背包

    const int N=1e3+7;
    int f[N],w[N],c[N];
    int main(void)
    {
    	int n=gi,V=gi;
    	for(int i=1;i<=n;++i)c[i]=gi,w[i]=gi;
    	for(int i=1;i<=n;++i)
    		for(int j=V;j>=a[i];--j)
    			chkmax(f[j],f[j-c[i]]+w[i]);
    	return 0;
    }
    

    完全背包

    const int N=1e3+7;
    int f[N],w[N],c[N];
    int main(void)
    {
    	int n=gi,V=gi;
    	for(int i=1;i<=n;++i)c[i]=gi,w[i]=gi;
    	for(int i=1;i<=n;++i)
    		for(int j=a[i];j<=V;++j)
    			chkmax(f[j],f[j-c[i]]+w[i]);
    	return 0;
    }
    

    多重背包

    略,(单调队列我也不会啊)

    树状数组

    struct BIT{
    	int c[N];
        inline void add(int x,int y){
            for(;x<=n;x+=x&-x)c[x]+=y;
        }
        inline int query(int x){
            int ret=0;
            for(;x;x-=x&-x)ret+=c[x];
            return ret;
        }
    };
    

    线段树

    const int N=1e5+7;
    struct SegmentTree{
    	int sum[N<<2],tag[N<<2];
    	#define ls (rt<<1)
    	#define rs (rt<<1|1)
    	#define mid ((l+r)>>1)
    	inline void pushtag(int rt,int l,int r,int v){
    		tag[rt]+=v,sum[rt]+=(r-l+1)*v;
    	}
    	inline void pushdown(int rt,int l,int r)
    	{
    		if(tag[rt]){
    			pushtag(ls,l,mid,tag[rt]);
    			pushtag(rs,mid+1,r,tag[rt]);
    			tag[rt]=0;
    		}
    	}
    	inline void pushup(int rt){
    		sum[rt]=sum[ls]+sum[rs];
    	}
    	inline void modify(int rt,int l,int r,int L,int R,int v){
    		if(L<=l&&r<=R){
    			pushtag(rt,l,r,v);
    			return;
    		}
    		pushdown(rt,l,r);
    		if(L<=mid)modify(ls,l,mid,L,R,v);
    		if(R>mid)modify(rs,mid+1,r,L,R,v);
    		pushup(rt);
    	}
    	inline int query(int rt,int l,int r,int L,int R){
    		if(L<=l&&r<=R)return sum[rt];
    		pushdown(rt,l,r);
    		int ret=0;
    		if(L<=mid)ret+=query(ls,l,mid,L,R);
    		if(R>mid)ret+=query(rs,mid+1,r,L,R);
    		return ret;
    	}
    };
    

    Miller_Rabin

    bool Test(ll a,ll x)
    {
        if(a>=x)return 1;
        ll ret=qpow(a,x-1,x),s=x^1;
        while(ret==1&&!(s&1))s>>=1,ret=qpow(a,s,x);
        return ret==1||ret==(x^1);
    }
    /*
    可以从后往前检测,似乎会更快
    bool Test(ll a,ll x)
    {
    	if(a>=x)return 1;
    	ll ret,s=x^1;
    	int p=__builtin_ctzll(s);
    	ret=qpow(a,s>>p,x);
    	if(ret==1||ret==(x^1))return 1;
    	while(p--&&ret!=(x^1))ret=mul(ret,ret,x);
    	return p>=0;
    }
    */
    

    线性筛

    int npr[N],pr[N],cnt;
    void sieve(int n)
    {
        npr[1]=1;
        for(int i=2;i<=n;++i){
            if(!npr[i]){
                pr[++cnt]=i;
            }
            for(int j=1;j<=cnt&&pr[j]*i<=n;++j)
            {
                npr[pr[j]*i]=1;
                if(i%pr[j]==0)break;
            }
        }
    }
    

    普通平衡树

    const int N=1e5+7;
    int top,cnt;
    struct SplayTree{
    	struct node;
    	typedef node* tree;
    	struct node{
    		int val,siz,cnt;
    		tree par,ch[2];
    		node(){}
    		node(int v,tree fa):val(v),siz(1),cnt(1),par(fa){ch[0]=ch[1]=NULL;}
    	}*root;
    	static node pool[N<<2],*stk[N<<2];
    	inline tree newnode(int val,tree par){return &(*(top?stk[top--]:pool+(++cnt))=node(val,par));}
    	inline void delnode(tree &x){stk[++top]=x,x=NULL;}
    	inline int siz(tree x){return x?x->siz:0;}
    	inline bool ws(tree x,tree p){return p?p->ch[1]==x:0;}
    	inline void pushup(tree x){if(x)x->siz=siz(x->ch[0])+siz(x->ch[1])+x->cnt;}
    	inline void connect(tree x,tree p,bool wson){x?x->par=p:0,(p?p->ch[wson]:root)=x;}
    	inline void rotate(tree x){
    		tree p=x->par,g=p->par;
    		bool t=ws(x,p);
    		connect(x,g,ws(p,g));
    		connect(x->ch[!t],p,t);
    		connect(p,x,!t);
    		pushup(p);
    	}
    	inline tree adjust(tree x,bool p,bool q)
    	{
    		tree k=x->ch[p];
    		while(k&&k->ch[q])k=k->ch[q];
    		return Splay(k,x),x;
    	}
    	inline tree Splay(tree x,tree y=NULL){
    		while(x&&x->par!=y){
    			tree p=x->par,g=p->par;
    			if(g!=y)rotate(ws(x,p)^ws(p,g)?x:p);
    			rotate(x);
    		}
    		return pushup(x),x;
    	}
    	inline tree find(int val){
    		tree x=root;
    		while(x&&x->val!=val&&x->ch[val>x->val])x=x->ch[val>x->val];
    		return Splay(x),x;
    	}
    	inline tree findkth(int k){
    		tree x=root;
    		while(x)
    			if(siz(x->ch[0])+x->cnt>=k&&siz(x->ch[0])<k)return x;
    			else if(siz(x->ch[0])>=k)x=x->ch[0];
    			else k-=siz(x->ch[0])+x->cnt,x=x->ch[1];
    		assert(0);
    	}
    	inline void erase(int val){
    		tree x=find(val);
    		if(x->cnt>1)return --x->cnt,void();
    		adjust(x,0,1);
    		connect(x->ch[0],NULL,0),connect(x->ch[1],root,1);
    		delnode(x);
    	}
    	inline tree insert(int val){
    		if(!root)return root=newnode(val,NULL);
    		for(tree x=root;x;x=x->ch[val>x->val])
    		{
    			if(x->val==val)return ++x->cnt,Splay(x);
    			if(!x->ch[val>x->val])return Splay(x->ch[val>x->val]=newnode(val,x));
    		}
    	}
    	inline int rank(int x){return siz(find(x)->ch[0])+1;}
    	inline tree pre(int x){
    		tree tmp=adjust(insert(x),0,1)->ch[0];
    		return erase(x),tmp;
    	}
    	inline tree nxt(int x){
    		tree tmp=adjust(insert(x),1,0)->ch[1];
    		return erase(x),tmp;
    	}
    }bt;
    SplayTree::node SplayTree::pool[N<<2],*SplayTree::stk[N<<2];
    

    单源最短路(堆优化(dijkstra))

    typedef pair<int,int> pii;
    priority_queue<pii,vector<pii>,greater<pii> >Q;
    int vis[N],dis[N];
    inline void dijkstra(){
    	memset(dis,127,sizeof dis);
        dis[S]=0;
        Q.push(pii(0,S));
        while(!Q.empty())
        {
            int now=Q.top().second;Q.pop();
            if(vis[now])continue;
            vis[now]=1;
            for(int i=head[now];~i;i=e[i].nxt){
                int v=e[i].v;
                if(dis[v]>dis[now]+e[i].w){
                    dis[v]=dis[now]+e[i].w;
                    if(!vis[v])Q.push(pii(dis[v],v));
                }
            }
        }
    }
    

    单源最短路(SPFA)

    int dis[N],vis[N];
    queue<int>Q;
    inline void spfa()
    {
        memset(dis,127,sizeof dis);
        dis[S]=0;
        Q.push(S);
        while(!Q.empty())
        {
            int now=Q.front();Q.pop();
            vis[now]=0;
            for(int i=head[now];~i;i=e[i].nxt){
                int v=e[i].v;
                if(dis[v]>dis[now]+e[i].w){
                    dis[v]=dis[now]+e[i].w;
                    if(!vis[now])Q.push(now),vis[now]=1;
                }
            }
    	}
    }
    

    (ST)

    #define lg2(x) (31-__builtin_clz(x))
    int f[21][N],a[N];
    inline void STinit(int n){
        int len=lg2(n);
       	for(int i=1;i<=n;++i)f[0][i]=a[i];
        for(int i=1;i<=len;++i)
            for(int j=1;j+(1<<i)-1<=n;++j)
                f[i][j]=min(f[i-1][j],f[i-1][j+(1<<i)-1]);
    }
    inline int Query(int l,int r){
        if(l>r)swap(l,r);
        int k=lg2(r-l+1);
        return min(f[k][l],f[k][r-(1<<k)+1]);
    }
    

    文艺平衡树

    struct SplayTree{
    	struct node;
    	typedef node* tree;
    	struct node{
    		int val,siz,rev;
    		tree par,ch[2];
    		node(){}
    		node(int v,tree fa):val(v),siz(1),rev(0),par(fa){ch[0]=ch[1]=NULL;}
    	}*root;
    	inline int siz(tree x){return x?x->siz:0;}
    	inline bool ws(tree x,tree p){return p?p->ch[1]==x:0;}
    	inline void connect(tree x,tree p,bool which){x?x->par=p:0,(p?p->ch[which]:root)=x;}
    	inline void pushup(tree x){if(x)x->siz=siz(x->ch[0])+siz(x->ch[1])+1;}
    	inline void pushtag(tree x){if(x)std::swap(x->ch[0],x->ch[1]),x->rev^=1;}
    	inline void pushdown(tree x){if(x&&x->rev)pushtag(x->ch[0]),pushtag(x->ch[1]),x->rev=0;}
    	inline int size(){return siz(root);}
    	inline void rotate(tree x)
    	{
    		tree p=x->par,g=p->par;
    		bool t=ws(x,p);
    		connect(x,g,ws(p,g));
    		connect(x->ch[!t],p,t);
    		connect(p,x,!t);
    		pushup(p);
    	}
    	inline tree Splay(tree x,tree y=NULL)
    	{
    		while(x&&x->par!=y){
    			tree p=x->par,g=p->par;
    			if(g!=y)rotate(ws(x,p)^ws(p,g)?x:p);
    			rotate(x);
    		}
    		return pushup(x),x;
    	}
    	inline tree adjust(tree x,bool p,bool q){
    		tree k=x->ch[p];
    		while(k&&k->ch[q])k=k->ch[q];
    		return Splay(k,x),x;
    	}
    	inline tree findkth(int k){
    		if(k<1||k>size())return NULL;
    		tree x=root;
    		while(x)
    		{
    			pushdown(x);
    			if(siz(x->ch[0])+1==k)return x;
    			else if(siz(x->ch[0])>=k)x=x->ch[0];
    			else k-=siz(x->ch[0])+1,x=x->ch[1];
    		}
    	}
    	inline tree split(int l,int r){
    		if(l>r)return NULL;
    		tree L=findkth(l-1),R=findkth(r+1);
    		Splay(L),Splay(R,L);
    		return l==1&&r==size()?root:(l==1?root->ch[0]:(r==size()?root->ch[1]:root->ch[1]->ch[0]));
    	}
    	inline void reverse(int l,int r){
    		tree x=split(l,r);
    		pushtag(x);
    	}
    	inline void merge(tree &a,tree &b){
    		if(!a)return std::swap(b,a),void();
    		if(!b)return;
    		if(a->ch[1])
    		{
    			adjust(a,1,1);
    			connect(b,a->ch[1],1);
    			pushup(a->ch[1]);
    		}
    		else connect(b,a,1);
    		pushup(a);
    	}
    	inline tree cut(tree x){
    		if(!x)return NULL;
    		tree p=x->par;
    		if(p)p->ch[ws(x,p)]=0;
    		x->par=0;
    		return pushup(p),p;
    	}
    	inline void swap(int l1,int r1,int l2,int r2){
    		int siz1=r1-l1+1,siz2=l2-r1-1,siz3=r2-l2+1;
    		tree a=split(1,l1-1);cut(a);
    		tree b=split(1,siz1);cut(b);
    		tree c=split(1,siz2);cut(c);
    		tree d=split(1,siz3),e=cut(d);
    		merge(a,d),merge(a,c),merge(a,b),merge(a,e);
    		root=a;
    	}
    	inline tree insert(int val){
    		if(!root)return root=new node(val,NULL);
    		if(root->ch[1])
    		{
    			adjust(root,1,1);
    			return Splay(root->ch[1]->ch[1]=new node(val,root->ch[1]));
    		}
    		return Splay(root->ch[1]=new node(val,root));
    	}
    	inline void print(){_print(root);}
    	inline void _print(tree x){
    		if(!x)return ;
    		pushdown(x);
    		_print(x->ch[0]);
    		pi(x->val,' ');
    		_print(x->ch[1]);
    	}
    	inline tree build(int l,int r,int a[]){
    		if(l>r)return NULL;
    		int mid=(l+r)>>1;
    		tree x=new node(a[mid],NULL);
    		connect(build(l,mid-1,a),x,0);
    		connect(build(mid+1,r,a),x,1);
    		return pushup(x),x;
    	}
    	inline void rebuild(int n,int a[]){root=build(1,n,a);}
    	inline void join(SplayTree &b){merge(root,b.root);}
    };
    
  • 相关阅读:
    2007年12月英语四级预测作文大全1
    2007年12月英语四级预测作文大全3
    2007年12月英语四级预测作文大全2
    2007年12月英语四级预测作文大全3
    2007年12月英语四级预测作文大全2
    2007年12月英语四级预测作文大全3
    2007年12月英语四级预测作文大全2
    2007年12月英语四级预测作文大全3
    2007年12月英语四级预测作文大全2
    2007年12月英语四级预测作文大全2
  • 原文地址:https://www.cnblogs.com/LLCSBlog/p/11830522.html
Copyright © 2020-2023  润新知