总结一下常用的模板,方便自己使用。
1.最大公约数(欧几里得)和最小公倍数
1 typedef long long LL; 2 3 LL gcd(LL a,LL b){ 4 return (b==0) ? a : gcd(b,a%b); 5 } 6 7 LL lcm(LL a,LL b){ 8 return a/gcd(a,b)*b; 9 }
2.扩展欧几里得
1 typedef long long LL; 2 3 LL e_gcd(LL a,LL b,LL &x,LL &y){ 4 LL d=a; 5 if(b!=0){ 6 d=e_gcd(b,a%b,y,x); 7 y-=(a/b)*x; 8 } 9 else{x=1;y=0;} 10 return d; 11 }//a*x+b*y=d;得到x,y,gcd(a,b);
3.并查集
1 //递归版路径压缩 2 int find(int x){return x==Father[x]?x:Father[x]=find(Father[x]);} 3 4 void Union(int x,int y){ 5 int fx=find(x),fy=find(y); 6 if(fx!=fy) Father[fx]=fy; 7 }//合并
4.快速幂
1 //普通快速幂 2 typedef long long LL; 3 LL fast_mod(LL x,LL n,LL mod){ 4 LL ans=1; 5 while(n>0){ 6 if(n&1) ans=(ans*x)%mod; 7 x=(x*x)%mod; 8 n>>=1; 9 } 10 return ans; 11 }
5.素数筛
1 //埃氏筛法 2 int prime[N]; 3 bool is_prime[N+1]; 4 5 //返回n以内素数的个数 6 int sieve(int n){ 7 int p=0; 8 for(int i=0;i<=n;i++) is_prime[i]=1; 9 is_prime[0]=is_prime[1]=0; 10 for(int i=2;i<=n;i++){ 11 if(is_prime[i]){ 12 prime[p++]=i; 13 for(int j=2*i;j<=n;j+=i) is_prime[j]=0; 14 } 15 } 16 return p; 17 }
6.三大基础背包
1 void ZeroOnePack(int cost,int value){//01 2 for(int j=v;j>=cost;j--){ 3 dp[j]=max(dp[j],dp[j-cost]+value); 4 } 5 } 6 7 void CompletePack(int cost,int value){//完全 8 for(int j=cost;j<=v;j++){ 9 dp[j]=max(dp[j],dp[j-cost]+value); 10 } 11 } 12 13 void MultiplePack(int cost,int value,int cnt){//多重 14 if(v<=cnt*cost){//如果总容量比这个物品的容量要小,那么这个物品可以直到取完,相当于完全背包. 15 CompletePack(cost,value); 16 return ; 17 } 18 else{//否则就将多重背包转化为01背包 19 int k=1; 20 while(k<=cnt){ 21 ZeroOnePack(k*cost,k*value); 22 cnt=cnt-k; 23 k=2*k; 24 } 25 ZeroOnePack(cnt*cost,cnt*value); 26 } 27 }
7.欧拉函数
1 void Euler(){ 2 phi[1]=1; 3 for(int i=2;i<N;i++) phi[i]=i; 4 for(int i=2;i<N;i++){ 5 if(phi[i]==i){ 6 for(int j=i;j<N;j+=i) phi[j]=phi[j]/i*(i-1); 7 } 8 } 9 }
8.最短路
1 //Floyd:(任意两点间的最短路问题) 2 for(int k=0;k<n;k++) 3 for(int i=0;i<n;i++) 4 for(int j=0;j<n;j++) 5 dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]); 6 7 //Dijkstra(无负边时的最短路问题) 8 const int INF=0x3f3f3f3f; 9 const int N=111111; 10 11 vector < pair<int,int> > E[N]; 12 int n,m; 13 int d[N]; 14 15 void init(){ 16 for(int i=0;i<N;i++) d[i]=INF; 17 for(int i=0;i<N;i++) E[i].clear(); 18 } 19 20 void dijkstra(int s,int d[]){ 21 priority_queue <pair<int,int> > Q; 22 d[s]=0; 23 Q.push(make_pair(-d[s],s)); 24 25 while(!Q.empty()){ 26 int now=Q.top().second; 27 Q.pop(); 28 for(int i=0;i<E[now].size();i++){ 29 int v=E[now][i].first; 30 int D=d[now]+E[now][i].second; 31 if(d[v]>D){ 32 d[v]=D; 33 Q.push(make_pair(-d[v],v)); 34 } 35 } 36 } 37 }
9.线段树
1 typedef long long LL; 2 LL ans; 3 struct Tree 4 { 5 LL l,r; 6 LL sum,add; 7 }; 8 Tree tree[MAX*4]; 9 10 void pushup(LL x) 11 { 12 LL tmp=2*x; 13 tree[x].sum=tree[tmp].sum+tree[tmp+1].sum; 14 } 15 16 17 void pushdown(LL x) 18 { 19 LL tmp=2*x; 20 tree[tmp].add+=tree[x].add; 21 tree[tmp+1].add+=tree[x].add; 22 tree[tmp].sum+=tree[x].add*(tree[tmp].r-tree[tmp].l+1); 23 tree[tmp+1].sum+=tree[x].add*(tree[tmp+1].r-tree[tmp+1].l+1); 24 tree[x].add=0; 25 } 26 27 void build(int l,int r,int x) 28 { 29 tree[x].l=l; 30 tree[x].r=r; 31 tree[x].add=0; 32 if(l==r) 33 { 34 scanf("%lld",&tree[x].sum); 35 return ; 36 } 37 int tmp=x<<1; 38 int mid=(l+r)>>1; 39 build(l,mid,tmp); 40 build(mid+1,r,tmp+1); 41 pushup(x); 42 } 43 44 45 void update(LL l,LL r,LL c,LL x) 46 { 47 if(r<tree[x].l||l>tree[x].r) return ; 48 if(l<=tree[x].l&&r>=tree[x].r) 49 { 50 tree[x].add+=c; 51 tree[x].sum+=c*(tree[x].r-tree[x].l+1); 52 return ; 53 } 54 if(tree[x].add) pushdown(x); 55 LL tmp=x<<1; 56 update(l,r,c,tmp); 57 update(l,r,c,tmp+1); 58 pushup(x); 59 } 60 61 62 void query(LL l,LL r,LL x) 63 { 64 if(r<tree[x].l||l>tree[x].r) return ; 65 if(l<=tree[x].l&&r>=tree[x].r) 66 { 67 ans+=tree[x].sum; 68 return ; 69 } 70 if(tree[x].add) pushdown(x); 71 LL tmp=x<<1; 72 LL mid=(tree[x].l+tree[x].r)>>1; 73 if(r<=mid) query(l,r,tmp); 74 else if(l>mid) query(l,r,tmp+1); 75 else 76 { 77 query(l,mid,tmp); 78 query(mid+1,r,tmp+1); 79 } 80 }
10.枚举全排列
1 //这个东西有可能扫描不到全部的,可以在前面sort一下再扫. 2 do{ 3 4 }while(next_permutation(num+1,num+1+n));//枚举全排列,输入从1开始,n个
时间: 2024-11-05 16:04:31