1. 程式人生 > >常用模板(持續更新)

常用模板(持續更新)

ati make size one inf 最短路 返回 01背包 方便

總結一下常用的模板,方便自己使用。

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個 

常用模板(持續更新)