模板整理
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;
}

浙公网安备 33010602011771号