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自动机

原文地址:https://www.cnblogs.com/mrha/p/13608420.html