zoukankan      html  css  js  c++  java
  • ACM模板大整理

    gcd

    void gcd(int x,int y)
    {
    	return !y?x:gcd(y,x%y);
    }
    

    exgcd

    void ex_gcd(int a,int b,int &x,int &y)
    {
        if (!b)
        {
    		x=1;
    		y=0;
    		return ;
        }
        ex_gcd(b,a%b,y,x);
        y-=x*(a/b);
    }
    

    注:线性同余方程ax+by=c有解条件为c是gcd(a,b)的倍数
    令d=gcd(a,b) 通解公式为x=x0+b/dt y=y0+a/dt

    欧拉函数

    //O(n)筛法
    void make()
    {
        phi[1]=1;
        int N=maxn;
        int k;
        for(int i=2;i<N;i++)
        {
            if(!m[i])
                p[pt++]=m[i]=i,phi[i]=i-1;
            for(int j=0;j<pt && (k=p[j]*i)<N;j++)
            {
                m[k]=p[j];
                if(m[i]==p[j])
                {
                    phi[k]=phi[i]*p[j];
                    break;    
                }
                else
                    phi[k]=phi[i]*(p[j]-1);
                    f(i*k)=f(i)*f(k)
            }
        }
    }
    
    //O(sqrt(n))求单个数的欧拉值
    ll eular(ll n)
    {
        ll ans = n;
        for(int i=2; i*i <= n; ++i)
        {
            if(n%i == 0)
            {
                ans = ans/i*(i-1);
                while(n%i == 0)
                    n/=i;
            }
        }
        if(n > 1) ans = ans/n*(n-1);
        return ans;
    }
    

    筛法

    //欧拉筛法
    for(int i=2;i<=n;i++)
        {
            if(!vis[i])
            	prime[cnt++]=i;
            for(int j=0;j<cnt && i*prime[j]<=n; j++)
            {
                vis[i*prime[j]]=true; 
                if(i%prime[j]==0) break; 
            }
        }
    //埃拉托斯特尼筛法
    for (int i=2;i<=N;i++) is[i]=1;
    for (int i=2;i<=N;i++)
        if (is[i])
            for (int j=i*i;j<=2000;j+=i)
    	    is[j]=0;
    

    中国剩余定理

    int CRT(int a[],int m[],int n)
    {
        int M=1;
        int ans=0;
        for (int i=1;i<=n;i++)
    	M*=m[i];
        for (int i=1;i<=n;i++)
        {
    	int x,y;
    	int Mi=M/m[i];
    	exgcd(Mi,m[i],x,y);
    	ans=(ans+Mi*x*a[i])%M;
        }
        if (ans<0) ans+=M;
        return ans;
    }
    

    欧拉定理&费马小定理

    欧拉定理:对于任何两个互质的正整数a和m(m>1),有(a^{Phi(m)}equiv1(mod m))
    费马小定理:当m是质数时,(a^{m-1}equiv1(mod m))
    扩展欧拉定理:
    (a^{b} = a^{b%Phi(m)},gcd(a,m) = 1)
    (a^{b} = a^{b},gcd(a,m)=1 & b<Phi(m))
    (a^{b} = a^{b%Phi(m)+Phi(m)},gcd(a,m)=1 & b>=Phi(m))

    树状数组

    void modify(int x,int y)
    {
    	while (x<=n)
    	{
    		b[x]+=y;
    		x+=x&-x;
    	}
    }
    
    int query(int x)
    {
    	int ans=0;
    	while (x)
    	{
    		ans+=b[x];
    		x-=x&-x;
    	}
    	return ans;
    }
    

    st表

    for (int i=1;i<=18;i++)
    		for (int j=1;j+(1<<i)-1<=n;j++)
    			st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
    max(st[l][q],st[r-(1<<q)+1][q])
    

    手写堆

    struct Heap{
        int hp[N], pos[N], sze; 
        // hp[i]: corresponding vertex (original graph) of node i (heap)
        // pos[i]: corresponding node (heap) of vertex i (original graph)
        void move(int &x, int y){
            swap(hp[x], hp[y]);
            swap(pos[hp[x]], pos[hp[y]]);
            x = y;
        }
        void move_up(int x){
            while(x > 1 && dis[hp[x]] < dis[hp[x >> 1]])
                move(x, x >> 1);
        }
        void move_down(int x){
            while((x << 1) <= sze){
                int min_son = x << 1;
                if((x << 1) < sze && dis[hp[x << 1 | 1]] < dis[hp[x << 1]]) min_son = x << 1 | 1;
                if(dis[hp[x]] <= dis[hp[min_son]]) break;
                move(x, min_son);
            }
        }
        int top(){
            return hp[1];
        }
        void push(int u){
            hp[++sze] = u, pos[u] = sze;
            move_up(pos[u]);
        }
        void pop(){
            hp[1] = hp[sze--], pos[hp[1]] = 1;
            move_down(1);
        }
        void update(int u){
            move_up(pos[u]);
        }
    } heap;
    

    dij

    void dij()
    {
    	int r;
    	while (heap.sze)
    	{
    		r=heap.top();
    		heap.pop();
    		for (int i=head[r],v;i;i=edge[i].next)
    		{
    			v=edge[i].to;
    			if (edge[i].w>0 && dis[v]-edge[i].ds>dis[r])
    			{
    				dis[v]=dis[r]+edge[i].ds;
    				heap.update(v);
    			}
    		}
    	}
    }
    

    树链剖分

    #include<cstdio>
    #include<algorithm>
    typedef long long ll;
    #define N 30010
    using namespace std;
    int n,x,y,m,a[N],f[N],dfn[N],deep[N],head[N],cnt=1,tp[N],ref[N],t,son[N],size[N];
    char s[10];
    struct hhh
    {
        int to,next;
    }edge[2*N];
    struct node
    {
        int l,r,data,mx;
    }tre[4*N];
    
    int read()
    {
        int ans=0,fu=1;
        char j=getchar();
        for (;(j<'0' || j>'9') && j!='-';j=getchar()) ;
        if (j=='-') fu=-1,j=getchar();
        for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
        return ans*fu;
    }
    
    void add(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void dfs1(int x,int fa,int dep)
    {
        f[x]=fa;
        deep[x]=dep+1;
        int mx=0;
        for (int i=head[x],v;i;i=edge[i].next)
        {
    	v=edge[i].to;
    	if (v!=fa)
    	{
    	    dfs1(v,x,dep+1);
    	    size[x]+=size[v];
    	    if (size[v]>mx) son[x]=v,mx=size[v];
    	}
        }
        size[x]++;
    }
    
    void dfs2(int x,int top)
    {
        dfn[x]=++t;
        ref[t]=x;
        tp[x]=top;
        if (son[x]) dfs2(son[x],top);
        for (int i=head[x],v;i;i=edge[i].next)
        {
    	v=edge[i].to;
    	if (v!=son[x] && v!=f[x])
    	    dfs2(v,v);
        }
    }
    
    void build(int i,int l,int r)
    {
        tre[i].l=l;
        tre[i].r=r;
        if (l==r)
        {
    	tre[i].data=a[ref[l]];
    	tre[i].mx=a[ref[l]];
    	return ;
        }
        int mid=(l+r)>>1;
        build(i*2,l,mid);
        build(i*2+1,mid+1,r);
        tre[i].data=tre[i*2].data+tre[i*2+1].data;
        tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
    }
    
    void modify(int i,int x,int y)
    {
        if (tre[i].l==x && tre[i].l==tre[i].r)
        {
    	tre[i].data=y;
    	tre[i].mx=y;
    	return ;
        }
        int mid=(tre[i].l+tre[i].r)>>1;
        if (x>mid) modify(i*2+1,x,y);
        else modify(i*2,x,y);
        tre[i].data=tre[i*2].data+tre[i*2+1].data;
        tre[i].mx=max(tre[i*2].mx,tre[i*2+1].mx);
    }
    
    ll query(int i,int l,int r,int p)
    {
        if (tre[i].l==l && tre[i].r==r)
    	if (p) return tre[i].data;
    	else return tre[i].mx;
        int mid=(tre[i].l+tre[i].r)>>1;
        if (l>mid) return query(i*2+1,l,r,p);
        else if (r<=mid) return query(i*2,l,r,p);
        else if (p) return query(i*2,l,mid,p)+query(i*2+1,mid+1,r,p);
        else return max(query(i*2,l,mid,p),query(i*2+1,mid+1,r,p));
    }
    
    ll pathquery(int u,int v,int p)
    {
        ll ans=0,tmp=-1000000000;
        while (tp[u]!=tp[v])
        {
    	if (deep[tp[u]]<deep[tp[v]]) swap(u,v);
    	if (p) ans+=query(1,dfn[tp[u]],dfn[u],p);
    	else tmp=max(tmp,query(1,dfn[tp[u]],dfn[u],p));
    	u=f[tp[u]];
        }
        if (deep[u]>deep[v]) swap(u,v);
        if (p) return ans+query(1,dfn[u],dfn[v],p);
        else return max(tmp,query(1,dfn[u],dfn[v],p));
    }
    
    int main()
    {
        n=read();
        for (int i=1;i<n;i++)
        {
    	x=read();
    	y=read();
    	add(x,y);
    	add(y,x);
        }
        for (int i=1;i<=n;i++) a[i]=read();
        dfs1(1,0,0);
        dfs2(1,1);
        build(1,1,n);
        m=read();
        while (m--)
        {
    	scanf("%s",s);
    	x=read();
    	y=read();
    	if (s[1]=='M')
    	    printf("%lld
    ",pathquery(x,y,0));
    	else if (s[1]=='S')
    	    printf("%lld
    ",pathquery(x,y,1));
    	else modify(1,dfn[x],y);
        }
        return 0;
    }
    

    SG函数

    void get_sg()
    {
    	for (int i=1;i<=n;i++)
    	{
    		memset(mex,0,sizeof(mex));
    		for (int j=0;j+m<=i;j++)
    			mex[sg[j]^sg[i-j-m]]=1;
    		for (int j=0;j<=n;j++)
    			if (!mex[j])
    			{
    				sg[i]=j;
    				break;
    			}
    	}
    }
    
    void init()
    {
    	m[0]=1;
    	for (int i=1;i<7;i++) m[i]=m[i-1]*10; 
    	sg[0]=1;
    	for (int i=1,x;i<1000000;i++)
    	{
    		for (int j=0;j<6 && m[j]<=i;j++)
    		{
    			x=(i/m[j])%10;
    			if (!x) mex[sg[i/m[j]/10]]=i;
    			else for (int k=1;k<=x;k++)
    				if (k<x || i>=m[j+1]) mex[sg[i-k*m[j]]]=i;
    				else mex[sg[0]]=i;
    		}
    		for (int j=0;j<1000000;j++)
    			if (mex[j]!=i)
    			{
    				sg[i]=j;
    				break;
    			}
    	}
    }
    

    费用流

    bool bfs()
    {
        for (int i=s;i<=t;i++)
    	vis[i]=0,cur[i]=head[i],dis[i]=0x3f3f3f3f;
        q.push(s);
        dis[s]=0;
        vis[s]=1;
        while(!q.empty())
        {
    	int r=q.front();
    	q.pop();
    	vis[r]=0;
    	for (int i=head[r],v;i;i=edge[i].next)
    	{
    	    v=edge[i].to;
    	    if (edge[i].w>0 && dis[r]+edge[i].cost<dis[v])
    	    {
    		dis[v]=dis[r]+edge[i].cost;
    		if (!vis[v])
    		{
    		    vis[v]=1;
    		    q.push(v);
    		}
    	    }
    	}
        }
        return dis[t]!=0x3f3f3f3f;
    }
    
    int dfs(int x,int f)
    {
        if (x==t) return ANS+=f*dis[t],f;
        int ha=0,now;
        vis[x]=1;
        for (int &i=cur[x],v;i;i=edge[i].next)
        {
    	v=edge[i].to;
    	if (vis[v]) continue;
    	if (edge[i].w>0 && dis[v]==dis[x]+edge[i].cost)
    	{
    	    now=dfs(v,min(f-ha,edge[i].w));
    	    if (now)
    	    {
    		ha+=now;
    		edge[i].w-=now;
    		edge[i^1].w+=now;
    	    }
    	}
    	if (ha==f) return ha;
        }
        return ha;
    }
    

    Splay

    #include<cstdio>
    #define N 100010
    #define which(x) (ls[f[(x)]]==(x))
    using namespace std;
    int n,m,ls[N],rs[N],val[N],sze[N],cnt[N],f[N],root,idx;
    int read()
    {
        int ans=0,fu=1;
        char j=getchar();
        for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
        for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
        return ans*fu;
    }
     
    void updt(int x)
    {
        sze[x]=sze[ls[x]]+sze[rs[x]]+cnt[x];
    }
     
    void Rotate(int u)
    {
        int v=f[u],w=f[v],b=which(u)?rs[u]:ls[u];
        which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v);
        if (w) which(v)?ls[w]=u:rs[w]=u;
        f[u]=w,f[v]=u;
        if (b) f[b]=v;
        updt(v),updt(u);
    }
     
    void Splay(int x,int tar)
    {
        while (f[x]!=tar)
        {
    		if (f[f[x]]!=tar)
    		{
    		    if (which(f[x])==which(x)) Rotate(f[x]);
    		    else Rotate(x);
    		}
    		Rotate(x);
        }
        if (!tar) root=x;
    }
     
    int find(int x)
    {
        int u=root,v=0;
        while (u && val[u]!=x)
        {
    		v=u;
    		if (x<val[u]) u=ls[u];
    		else u=rs[u];
        }
        return u?u:v;
    }
     
    void insert(int x)
    {
        int u=root,v=0;
        while (u && val[u]!=x)
        {
    		v=u;
    		if (x<val[u]) u=ls[u];
    		else u=rs[u];
        }
        if (u && val[u]==x)
    	return (void)(cnt[u]++,sze[u]++,Splay(u,0));
        f[++idx]=v;
        sze[idx]=1;
        val[idx]=x;
        cnt[idx]=1;
        if (v) x<val[v]?ls[v]=idx:rs[v]=idx;
        Splay(idx,0);
    }
     
    int getmn(int x)
    {
        while (ls[x]) x=ls[x];
        return x;
    }
     
    int getmx(int x)
    {
        while (rs[x]) x=rs[x];
        return x;
    }
     
    void erase(int x)
    {
        int tmp=find(x);
        Splay(tmp,0);
        if (cnt[tmp]>1) cnt[tmp]--,sze[tmp]--;
        else if (!ls[tmp] || !rs[tmp]) root=ls[tmp]+rs[tmp],f[root]=0;
        else
        {
    		f[ls[tmp]]=0;
    		int u=getmx(ls[tmp]);
    		Splay(u,0);
    		rs[u]=rs[tmp];
    		f[rs[tmp]]=u;
    		updt(u);
        }
    }
     
    int getkth(int k)
    {
        int cur=root;
        while (cur)
        {
    		if (sze[ls[cur]]>=k) cur=ls[cur];
    		else if (sze[ls[cur]]+cnt[cur]>=k) return val[cur];
    		else k-=sze[ls[cur]]+cnt[cur],cur=rs[cur];
        }
        return val[cur];
    }
     
    int getrank(int x)
    {
        int cur=find(x);
        Splay(cur,0);
        return sze[ls[cur]]+1;
    }
    int getpre(int x)
    {
        int cur=find(x);
        if (val[cur]<x) return val[cur];
        Splay(cur,0);
        return val[getmx(ls[cur])];
    }
     
    int getnxt(int x)
    {
        int cur=find(x);
        if (val[cur]>x) return val[cur];
        Splay(cur,0);
        return val[getmn(rs[cur])];
    }
     
    int main()
    {
        n=read();
        for (int i=1,op,a;i<=n;i++)
        {
    		op=read();
    		a=read();
    		if (op==1) insert(a);
    		if (op==2) erase(a);
    		if (op==3) printf("%d
    ",getrank(a));
    		if (op==4) printf("%d
    ",getkth(a));
    		if (op==5) printf("%d
    ",getpre(a));
    		if (op==6) printf("%d
    ",getnxt(a));
        }
        return 0;
    }
    
    #include<cstdio>
    #define N 200010
    #define inf 1e9+7
    #define which(x) (ls[f[(x)]]==(x))
    typedef long long ll;
    using namespace std;
    int n,m,ls[N],rs[N],id[N],lz[N],f[N],root,idx;
    ll sum[N],sze[N],val[N];
    char s[10];
    
    int read()
    {
        int ans=0,fu=1;
        char j=getchar();
        for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
        for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
        return ans*fu;
    }
    
    void push(int x)
    {
    	if (!lz[x]) return ;
    	if (ls[x])
    	{
    		val[ls[x]]+=lz[x];
    		lz[ls[x]]+=lz[x];
    		sum[ls[x]]+=1LL*sze[ls[x]]*lz[x];
    	}
    	if (rs[x]) 
    	{
    		val[rs[x]]+=lz[x];
    		lz[rs[x]]+=lz[x];
    		sum[rs[x]]+=1LL*sze[rs[x]]*lz[x];
    	}
    	lz[x]=0; 
    }
    
    void updt(int x)
    {
        sum[x]=sum[ls[x]]+sum[rs[x]]+val[x];
        sze[x]=sze[ls[x]]+sze[rs[x]]+1;
    }
     
    void Rotate(int u)
    {
        int v=f[u],w=f[v],b=which(u)?rs[u]:ls[u];
        //push(v);push(u);
        which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v);
        if (w) which(v)?ls[w]=u:rs[w]=u;
        f[u]=w,f[v]=u;
        if (b) f[b]=v;
        updt(v),updt(u);
    }
    
    int find(int x)
    {
        int u=root,v=0;
        while (u && id[u]!=x)
        {
    		v=u;
    		if (x<id[u]) u=ls[u];
    		else u=rs[u];
        }
        return u?u:v;
    }
    
    void Splay(int x,int tar)
    {
    	static int stk[N];
    	int tp=0;
    	stk[++tp]=x;
    	while (f[stk[tp]]) stk[tp+1]=f[stk[tp]],tp++;
    	while (tp) push(stk[tp--]);
        while (f[x]!=tar)
        {
    		if (f[f[x]]!=tar)
    		{
    		    if (which(f[x])==which(x)) Rotate(f[x]);
    		    else Rotate(x);
    		}
    		Rotate(x);
        }
        if (!tar) root=x;
    }
     
    void prt()
    {
    	for (int i=1;i<=idx;i++)
    		printf("%d: f %d ls %d rs %d sze %lld val %d lz %d id %d sum %lld
    ",i,f[i],ls[i],rs[i],sze[i],val[i],lz[i],id[i],sum[i]);
    }
    
    void insert(int x,int y)
    {
        int u=root,v=0;
        while (u && id[u]!=x)
        {
        	push(u);
    		v=u;
    		if (x<id[u]) u=ls[u];
    		else u=rs[u];
        }
        f[++idx]=v;
        id[idx]=x;
        sum[idx]=y;
        sze[idx]=1;
        val[idx]=y;
        if (v) x<id[v]?ls[v]=idx:rs[v]=idx;
        Splay(idx,0);
    }
    
    int getmn(int x)
    {
        while (ls[x]) x=ls[x];
        return x;
    }
     
    int getmx(int x)
    {
        while (rs[x]) x=rs[x];
        return x;
    }
    
    int getpre(int x)
    {
        int cur=find(x);
        if (id[cur]<x) return cur;
        Splay(cur,0);
        return getmx(ls[cur]);
    }
     
    int getnxt(int x)
    {
        int cur=find(x);
        if (id[cur]>x) return cur;
        Splay(cur,0);
        return getmn(rs[cur]);
    }
    
    ll query(int x,int y)
    {
    	int l=getpre(x),r=getnxt(y);
    	Splay(l,0);Splay(r,l);
    	return sum[ls[r]];
    }
    
    void modify(int x,int y,int z)
    {
    	int l=getpre(x),r=getnxt(y);
    	//printf("modify find l: %d r: %d
    ",l,r);
    	Splay(l,0);Splay(r,l);
    	lz[ls[r]]+=z;
    	val[ls[r]]+=z;
    	sum[ls[r]]+=1LL*sze[ls[r]]*z;
    	//prt();
    	Splay(ls[r],0);
    }
    
    void dlt(int x,int y)
    {
    	int l=getpre(x),r=getnxt(y);
    	Splay(l,0);Splay(r,l);
    	ls[r]=0;
    	Splay(r,0);
    }
    
    int main()
    {
        n=read();
        insert(-inf,0);
        insert(inf,0);
        for (int i=1,a,b,c;i<=n;i++)
        {
    		scanf("%s",s+1);
    		a=read();b=read();
    		if (s[1]=='I') insert(a,b);
    		else if (s[1]=='Q') printf("%lld
    ",query(a,b));
    		else if (s[1]=='M')
    		{
    			c=read();
    			modify(a,b,c);
    		}
    		else dlt(a,b);
    		//prt();
        }
        return 0;
    }
    
    

    完全背包

    for(int i=1; i<=n; i++)
       for(int j=w[i]; j<=V; j++)//注意此处,与0-1背包不同,这里为顺序,0-1背包为逆序
          f[j]=max(f[j],f[j-w[i]]+c[i]);
    printf("max=%d
    ",f[V]);
    

    匈牙利

    bool find(int x)
    {
    	for (int i=head[x];i;i=edge[i].next)
    	{
    		if (vis[edge[i].to]) continue;
    		vis[edge[i].to]=1;
    		if (!lover[edge[i].to] || find(lover[edge[i].to]))
    		{
    			lover[edge[i].to]=x;
    			return 1;
    		}
    	}
    	return 0;
    }
    

    网络流

    bool bfs()
    {
        memset(level,-1,sizeof(level));
        level[1]=0;
        p.push(1);
        while (!p.empty())
        {
    	int r=p.front();
    	for (int i=head[r];i;i=flow[i].next)
    	{
    	    int ha=flow[i].to;
    	    if (level[ha]==-1 && flow[i].w>0)
    	    {
    		level[ha]=level[r]+1;
    		p.push(ha);
    	    }
    	}
    	p.pop();
        }
        if (level[m]!=-1) return 1;
        return 0;
    }
     
    int dfs(int now,int f)
    {
        if (now==m) return f;
        for (int i=head[now];i;i=flow[i].next)
        {
    	if (flow[i].w>0 && level[flow[i].to]>level[now])
    	{
    	    int ha=dfs(flow[i].to,min(flow[i].w,f));
    	    if (ha)
    	    {
    		flow[i].w-=ha;
    		flow[i^1].w+=ha;
    		return ha;
    	    }
    	}
        }
        return 0;
    }
    

    Tarjan

    //有向图
    void Tarjan(int x)
    {
    	int v;
    	dfn[x]=low[x]=++t;
    	stk.push(x);
    	instk[x]=1;
    	for (int i=head[x];i;i=edge[i].next)
    	{
    		v=edge[i].to;
    		if (!dfn[v])
    		{
    			Tarjan(v);
    			low[x]=min(low[v],low[x]);
    		}
    		else if (instk[v])
    			low[x]=min(dfn[v],low[x]); 
    	}
    	if (dfn[x]==low[x])
    	{
    		++num;
    		do
    		{
    			v=stk.top();
    			stk.pop();
    			bel[v]=num;
    			instk[v]=0;
    			sum[num]++;
    		}while (v!=x);
    	}
    }
    //无向图
    void Tarjan(int x)
    {
        dfn[x]=low[x]=++t;
        for (int i=head[x],v;i;i=edge[i].next)
        {
    		v=edge[i].to;
    		if (i==(from[x]^1)) continue;
    		if (!dfn[v])
    		{
    		    from[v]=i;
    		    Tarjan(v);
    		    low[x]=min(low[v],low[x]);
    		    if (low[v]>dfn[x]) is[i]=is[i^1]=1,num++;
    		}
    		else low[x]=min(dfn[v],low[x]);
        }
    }
    

    2-SAT

    #include<cstdio>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<vector>
    #define N 3005
    #define M 500010
    using namespace std;
    int n,m,cnt=1,head[2*N],color[2*N],op[2*N];
    int dfn[2*N],low[2*N],id[2*N],num,tm,in[2*N];
    char u,v;
    bool wa=1,instk[2*N];
    stack <int> stk;
    queue <int> q;
    vector <int> dag[2*N];
    struct hhh
    {
        int to,next;
    }edge[4*M];
    
    inline int _(int x)
    {
        return x>n?x-n:x+n;
    }
    
    void add(int u,int v)
    {
        edge[cnt].to=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    
    void Tarjan(int x)
    {
        dfn[x]=low[x]=++tm;
        stk.push(x);
        instk[x]=1;
        for (int i=head[x],r;i;i=edge[i].next)
        {
    		r=edge[i].to;
    		if (!dfn[r])
    		{
    		    Tarjan(r);
    		    low[x]=min(low[x],low[r]);
    		}
    		else if (instk[r]) low[x]=min(low[x],dfn[r]);
        }
        int y;
        if (dfn[x]==low[x])
        {
    		++num;
    		do
    		{
    		    y=stk.top();
    		    stk.pop();
    		    instk[y]=0;
    		    id[y]=num;
    		}while(y!=x);
        }
    }
    
    void init()
    {
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(id,0,sizeof(id));
        memset(color,0,sizeof(color));
        memset(op,0,sizeof(op));
        memset(head,0,sizeof(head));
        memset(in,0,sizeof(in));
        for (int i=1;i<=2*n;i++) dag[i].clear();
        cnt=1;
        wa=1;
    	tm=num=0;
    }
    
    void buildgraph()
    {
    	for (int i=1,a,b;i<=m;i++)
    	{
    	    scanf("%d%c%d%c",&a,&u,&b,&v);
    	    a++;
    	    b++;
    	    if (u=='h') a+=n;
    	    if (v=='h') b+=n;
    	    add(a,_(b));
    	    add(b,_(a));
    	}
    	add(1,1+n);
    }
    
    void buildnew()
    {
    	for(int i=1;i<=2*n;i++)  
        {   
            for(int j=head[u];j;j=edge[j].next)  
            {  
                int v=edge[j].to;  
                if(id[i]!=id[v]) dag[id[v]].push_back(id[i]),in[id[i]]++;  
            } 
        }
    }
    
    void topo()
    {
    	for (int i=1;i<=tm;i++) if (in[i]==0) q.push(i);
    	while (!q.empty())
    	{
    		int r=q.front();
    		q.pop();
    		int size=dag[r].size();  
            if(!color[r]) color[r] = 1, color[op[r]] = 2;  
            for(int i=0;i<size;i++)  
            {  
                int v=dag[r][i];  
                in[v]--;  
                if(in[v]==0) q.push(v);  
            }  
    	}
    }
    
    int main()
    {
        while (~scanf("%d%d",&n,&m) && (n && m))
        {
    		init();
    		buildgraph();
    		for (int i=1;i<=2*n;i++) if (!dfn[i]) Tarjan(i);
    		for (int i=1;i<=n;i++)
    		    if (id[i]==id[i+n]) wa=0;
    		    else op[id[i]]=id[i+n],op[id[i+n]]=id[i];  
    		if (!wa) 
    		{
    		    printf("bad luck
    ");
    		    continue;
    		}
    		buildnew();
    		topo();
    		for (int i=2;i<=n;i++)
    		{
    			if (color[id[i]]==color[id[1]]) printf("%dw ",i-1);
    			else printf("%dh ",i-1);
    		}
    		printf("
    ");
        }
        return 0;
    }
    

    kmp

    for (int i=2,j=0;i<=lb;i++)
    	{
    		while (j && b[j+1]!=b[i]) j=next[j];
    		if (b[j+1]==b[i]) j++;
    		next[i]=j;
    	}
    	for (int i=1,j=0;i<=la;i++)
    	{
    		while (j && b[j+1]!=a[i]) j=next[j];
    		if (b[j+1]==a[i]) j++;
    		if (j==lb) j=next[j],printf("%d
    ",i-lb+1);
    	}
    

    manacher

    scanf("%s",s+1);
        s[0]='@';
        l=strlen(s+1);
        cnt++;
        for (int i=l;i>=1;i--) s[i*2]=s[i];
        for (int i=1;i<=2*l+1;i+=2) s[i]='#';
        s[2*l+2]='?';
        l=2*l+1;
        for (int i=1;i<=l;i++)
        printf("%c ",s[i]);
        putchar('
    ');
        mx=mxr=0;
        for (int i=1,x;i<=l;i++)
        {
            if (mxr>i) x=min(a[2*p-i],mxr-i);
            else x=1;
            while (s[i-x]==s[i+x]) x++;
            if (i+x>mxr) mxr=i+x,p=i;
            a[i]=x;
            printf("%d ",a[i]);
        }
    

    spfa

    void spfa(int x)
    {
        q.push(x);
        dis[x]=0;
        vis[x]=1;
        while (!q.empty())
        {
    		int r=q.front();
    		q.pop();
    		vis[r]=0;
    		for (int i=head[r],v;i;i=edge[i].next)
    		{
    		    v=edge[i].to;
    		    if (dis[v]-edge[i].w<dis[r])
    		    {
    				dis[v]=edge[i].w+dis[r];
    				if (!vis[v]) q.push(v),vis[v]=1;
    		    }
    		}
        }
    }
    

    最小生成树

    void _put(int x)
    {
    	for(int i=head[x];i;i=e[i].next)
    	if(!vis[e[i].to]) q.push(e[i]);
    }
    
    int prime()
    {
    	int Cnt=1,ret=0;
    	vis[1]=true;
    	_put(1);
    	while(Cnt<n)
    	{
    		while(1)
    		{
    			edge a=q.top();
    			if(!vis[a.to])
    			{
    				vis[a.to]=1;
    				Cnt++;
    				ret+=a.w;
    				_put(a.to);
    				break;
    			}
    			q.pop();
    		}
    	}
    	return ret;
    }
    
    for (int i=1;i<=m;i++)
    	{
    		if (cnt==n-k) break;
    		int xx=findfa(edge[i].u),yy=findfa(edge[i].v);
    		if (xx!=yy) 
    		{
    			f[xx]=yy;
    			ans+=edge[i].w;
    			cnt++;
    		}
    	}
    

    01背包

    	for (int i=1;i<=n;i++)
    		for (int j=v;j>=a[i];j--)
    			dp[j]=max(dp[j],dp[j-a[i]]+b[i]);
    

    后缀数组

    void suffix_sort()
    {
        int *x=buf1,*y=buf2,m=300;
        for (int i=0;i<=m;i++) buc[i]=0;
        for (int i=1;i<=n;i++) buc[x[i]=s[i]]++;
        for (int i=1;i<=m;i++) buc[i]+=buc[i-1];
        for (int i=n;i;i--) sa[buc[x[i]]--]=i;
        for (int k=1;k<=n;k<<=1)
        {
    	int p=0;
    	for (int i=n-k+1;i<=n;i++)
    	    y[++p]=i;
    	for (int i=1;i<=n;i++)
    	    if (sa[i]>k) y[++p]=sa[i]-k;
    	for (int i=0;i<=m;i++) buc[i]=0;
    	for (int i=1;i<=n;i++) buc[x[y[i]]]++;
    	for (int i=1;i<=m;i++) buc[i]+=buc[i-1];
    	for (int i=n;i;i--) sa[buc[x[y[i]]]--]=y[i];
    	swap(x,y),x[sa[1]]=p=1;
    	for (int i=2;i<=n;i++)
    	    if (y[sa[i]]==y[sa[i-1]] && y[sa[i]+k]==y[sa[i-1]+k])
    		x[sa[i]]=p;
    	    else x[sa[i]]=++p;
    	if ((m=p)>=n) break;
        }
        for (int i=1;i<=n;i++) rnk[sa[i]]=i;
        for (int i=1,j,k=0;i<=n;i++)
        {
    	if (rnk[i]==1) continue;
    	if (k) k--;
    	j=sa[rnk[i]-1];
    	while (s[i+k]==s[j+k] && i+k<=n && j+k<=n) k++;
    	height[rnk[i]]=k;
        }
    }
    

    AC自动机

  • 相关阅读:
    virtualbox使用相关问题
    mac os中的一些快捷键使用及基础软件安装
    U盘安装CentOS7
    Netbeans8下 Weblogic EJB案例
    Linux Weblogic 数据源 TimesTen配置
    JDBC操作TimesTen
    Red Hat TimesTen安装记录
    使用Protractor进行AngularJS e2e测试案例
    基于Karma和Jasmine的AngularJS测试
    protractor protractor.conf.js [launcher] Process exited with error code 1 undefined:1190
  • 原文地址:https://www.cnblogs.com/mrha/p/13608420.html
Copyright © 2011-2022 走看看