模板整理

1.并查集

int fa[maxn];
int n;
void init()
{
    for(int i=0;i<n;i++)
    {
        fa[i]=i;
    }
}
int findd(int i)
{
    if(fa[i]==i)
    {
        return i;
    }
    else return fa[i]=findd(fa[i]);
}
int unione(int x,int y)
{
    int fx=findd(x),fy=findd(y);
    if(fx!=fy)
    {
        fa[fx]=fy;
    }
}

 2.Dijkstra算法(n^2复杂度)

int maps[1005][1005]={0};
int vis[1005];
int dist[1005];
void fun()
{
    int i,j;
    for(i=0;i<1005;i++)
    {
        for(j=0;j<1005;j++)
        {
            if(i==j)
            {
                maps[i][j]=0;
            }
        }
    }
}
void dijstra(int n)
{
    memset(vis,0,sizeof(vis));
    fill(dist,dist+1005,100000);
    dist[1]=0;
    while(1)
    {
        int v=-1,i;
        for(i=1;i<=n;i++)
        {
            if(!vis[i]&&(dist[i]<dist[v]||v==-1))
            {
                v=i;
            }
        }
        if(v==-1)
        {
            break;
        }
        vis[v]=1;
        for(i=1;i<=n;i++)
        {
            if(maps[i][v]!=-1)
            {
                dist[i]=min(dist[i],dist[v]+maps[i][v]);
            }
        }
    }
}

 3.Floyd算法

 for(k=0;k<n;k++)
        {
            for(i=0;i<n;i++)
            {
                for(j=0;j<n;j++)
                {
                    //if(dp[i][k]<inf&&dp[k][j]<inf)
                    //{
                        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
                    //}
                }
            }
        }

 4.扩展欧几里得

int ex_gcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int ans=ex_gcd(b,a%b,x,y);//获得x2,y2;
    int temp=x;//存储x2
    x=y;//x1=y2
    y=temp-(a/b)*x;//y1=x2-(a/b)*y2
    return ans;
}

 5.KMP

void getnex()
{
    int i = 0, j = -1;
    nex[0] = -1;
    while(i < n)
    {
        if(j == -1 || s[i] == s[j])
        {
            i++, j++;
            nex[i] = j;

        }
        else j = nex[j];
    }
}
void getnt()
{
    int i = 0, j = -1;
    nex[0] = -1;
    while(s[i])
    {
        if(j == -1 || s[i] == s[j])
        {
            i++, j++;
           nex[i] = j;
        }
        else j = nex[j];
    }
    l1=i;
}
bool kmp(int l1,int l2)
{
    int i=0;
    int j=0;
    getnex(l2);
    for(i=0;i<l1;i++)
    {
        while(j&&s[i]!=t[j])
        {
            j=nex[j];
        }
        if(s[i]==t[j]) j++;
        if(j==l2) return true;
    }
    return false;
}
int kmp(char t[],char p[])
{
	int n=strlen(t+1),m=strlen(p+1);
	prefix(p);
	int sum=0;
	for(int i=1,q=0;i<=n;i++)
	{
		while(q>0 && p[q+1]!=t[i])
			q=nex[q];
		if(p[q+1]==t[i])
			q++;
		if(q==m)
		{
			sum++;
			q=nex[q];
		}
	}
	return sum;
}

 6.欧拉筛

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n;
int prime[10000005];
bool vis[10000005];
void primejudge(int n)
{
    memset(vis,false,sizeof(vis));
    int cnt=0;
    vis[1]=true;
    int i,j;
    for(i=2;i<=n;i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
        }
        for(j=0;j<cnt&&i*prime[j]<=n;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                break;
            }
        }
    }
}
int main()
{  int m;
    scanf("%d%d",&n,&m);
    primejudge(n);
    while(m--)
    {   int x;
        scanf("%d",&x);
        if(!vis[x])
        {
            cout<<"Yes"<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
    }
    return 0;
}
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n;
int prime[10000005];
bool vis[10000005];
void primejudge(int n)
{
    memset(vis,false,sizeof(vis));
    int cnt=0;
    vis[1]=true;
    int i,j;
    for(i=2;i<=n;i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
        }
        for(j=0;j<cnt&&i*prime[j]<=n;j++)
        {
            vis[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                break;
            }
        }
    }
}
int main()
{  int m;
    scanf("%d%d",&n,&m);
    primejudge(n);
    while(m--)
    {   int x;
        scanf("%d",&x);
        if(!vis[x])
        {
            cout<<"Yes"<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
    }
    return 0;
}

  

 7.SG博弈

 //f[N]:可改变当前状态的方式,N为方式的种类,f[N]要在getSG之前先预处理
 2 //SG[]:0~n的SG函数值
 3 //S[]:为x后继状态的集合
 4 int f[N],SG[MAXN],S[MAXN];
 5 void  getSG(int n){
 6     int i,j;
 7     memset(SG,0,sizeof(SG));
 8     //因为SG[0]始终等于0,所以i从1开始
 9     for(i = 1; i <= n; i++){
10         //每一次都要将上一状态 的 后继集合 重置
11         memset(S,0,sizeof(S));
12         for(j = 0; f[j] <= i && j <= N; j++)
13             S[SG[i-f[j]]] = 1;  //将后继状态的SG函数值进行标记
14         for(j = 0;; j++) if(!S[j]){   //查询当前后继状态SG值中最小的非零值
15             SG[i] = j;
16             break;
17         }
18     }
19 }

  欧拉函数打表

int p[maxn];
void phi()
{
    for(int i=2;i<maxn;i++)
        p[i]=0;
    p[1]=1;
    for(int i=2;i<maxn;i++)
    {
        if(!p[i])
            for(int j=i;j<=maxn;j+=i)
            {
                if(!p[j])p[j]=j;
                p[j]=p[j]/i*(i-1);
            }
    }
}

  

 逆元求组合数

#include <iostream>
#include <bits/stdc++.h>
#define maxn 1000005
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
ll fac[maxn],inv[maxn];
ll pow_mod(ll a,ll n)
{
    ll ret =1;
    while(n)
    {
        if(n&1) ret=ret*a%mod;
          a=a*a%mod;
          n>>=1;
    }
    return ret;
}
void init()
{
    fac[0]=1;
    for(int i=1;i<maxn;i++)
    {
        fac[i]=fac[i-1]*i%mod;
    }
}
ll C(ll x, ll y)
{
    return fac[x]*pow_mod(fac[y]*fac[x-y]%mod,mod-2)%mod;
}