快速幂取模
int Pow(int a,int b,int c)
{
int res=1;
while(b>0)
{
if(b&1) res=res*a%c;
a=a*a%c;
b>>=1;
}
return res;
}//复杂度O(logn)
gcd
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }
扩展欧几里得(递归)
int exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return a; } int r=exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*y; return r; }
递归实现n!
int fact(int n) { /*if(n==0||n==1) return 1; else return n*fact(n-1);*/ return n==0?1:fact(n-1)*n;//上面注释的简化版 }
背包类
01背包(每种物品只有一个)
//n 物品数量,v 背包容量 //size 单个物品体积,value 单个物品价值 void bag01() { for(int i=0;i<n;i++) for(int j=v;j>=size[i];j--) { dp[j]=max(dp[j],dp[j-size[i]]+value[i]); } cout<<dp[v]<<endl; }
完全背包(每种物品有无穷多)
void complete() { for(int i=0;i<n;i++) for(int j=size[i];j<=v;j++) { dp[j]=max(dp[j],dp[j-size[i]]+value[i]); } cout<<dp[v]<<endl; }
多重背包(每种物品数量有限)
//n 物品数量,v 背包容量 //size 单个物品体积,value 单个物品价值,num 该物品的数量 void multiply() { for(int i=0;i<n;i++) { int d1=1,d2=num[i]; while(d1<d2) { for(int j=v;j>=d1*size[i];j--) { dp[j]=max(dp[j],dp[j-d1*size[i]]+value[i]*d1); } d2-=d1; d1*=2; } for(int j=v;j>=d2*size[i];j--) dp[j]=max(dp[j],dp[j-d2*size[i]]+value[i]*d2); } cout<<dp[v]<<endl; }
1~n全排列(递归实现)
int vis[10];//用于标记是否被访问过,0--未访问 1--已访问 int ans[10];//用于存储答案 int step,n; void dfs(int step) { for(int i=1;i<=n;i++) { if(vis[i]==0) { vis[i]=1; ans[step]=i;//将答案存储 if(step<n) //调用递归 dfs(step + 1); //即相当于再一次从头执行一个dfs函数,可以理解为一个嵌套 else { for(int i=1;i<=n;i++) { printf("%d",ans[i]); if(i!=n) //用于控制输出格式 printf(" "); else printf("\n"); } } vis[i]=0; //访问完毕返回标记为可访问 //只有当输出了一个结果后才有可能执行 } } } int main() { memset(vis,0,sizeof(vis)); step=0; scanf("%d",&n); dfs(1); return 0; }
1~n全排列(利用STL)
void Full(int n) { for(int i=0;i<n;i++) a[i]=i+1; do { for(int i=0;i<n;i++) { if(i!=0) cout<<" "; cout<<a[i]; } cout<<"\n"; } while(next_permutation(a,a+n)); }
最长递增子序列
int a[maxn]; int dp[maxn]; int n; void longest() { dp[0]=a[0]; int pos; int L=1; for(int i=0;i<n;i++) { pos=lower_bound(dp,dp+L,a[i])-dp; dp[pos]=a[i]; L=max(L,pos+1); } cout<<L<<endl; }
DFS模板
void dfs()//参数用来表示状态 { if(到达终点状态) { ...//根据题意来添加 return; } if(越界或者是不符合法状态) return; for(扩展方式) { if(扩展方式所达到状态合法) { ....//根据题意来添加 标记; dfs(); 修改(剪枝); (还原标记); //是否还原标记根据题意 //如果加上(还原标记)就是 回溯法 } } }
判断1~1e9之内的数是不是素数
//是素数prime(n)==true bool prime(int n) { for(int i=2;i*i<=n;i++) if(n%i==0) return false; return n!=1; } vector<int> divisor(int n) { vector<int> res; for(int i=1;i*i<=n;i++) { if(n%i==0) { res.push_back(i); if(i!=n/i) res.push_back(n/i); } } return res; } map<int,int> factor(int n) { map<int,int> res; for(int i=2;i*i<=n;i++) { while(n%i==0) { ++res[i]; n/=i; } if(n!=1) res[n]=1; return res; } }
To be continued...