东拼西凑的模板·持续更新中

一.常用算法(应该不需要用到模板的那种常用)

1.1 快速幂

 1 //https://blog.csdn.net/java_c_android/article/details/55802041 
 2 long long quickmod(long long a,long long b,long long m)  
 3 {  
 4     long long ans = 1;  
 5     while(b)//用一个循环从右到左便利b的所有二进制位  
 6     {  
 7         if(b&1)//判断此时b[i]的二进制位是否为1  
 8         {  
 9             ans = (ans*a)%m;//乘到结果上,这里a是a^(2^i)%m  
10             b--;//把该为变0  
11         }  
12         b/=2;  
13         a = a*a%m;  
14     }  
15     return ans;  
16 }  
View Code

1.2 gcd

1 ll gcd(ll a,ll b){
2     return b==0?a:gcd(b,a%b);
3 }

二.素数

2.1 素数筛

 1 const int MAX = 100;
 2 //快速素数筛,只筛选小于等于素数i的素数与i的乘积,既不会造成重复筛选,又不会遗漏。时间复杂度几乎是线性的。
 3 //模板来源https://blog.csdn.net/stack_queue/article/details/53560887
 4 long long su[MAX],cnt;
 5 bool isprime[MAX];
 6 void prime()
 7 {
 8     cnt=1;
 9     memset(isprime,1,sizeof(isprime));//初始化认为所有数都为素数
10     isprime[0]=isprime[1]=0;//0和1不是素数
11     for(long long i=2;i<=MAX;i++)
12     {
13         if(isprime[i])
14             su[cnt++]=i;//保存素数i
15         for(long long j=1;j<cnt&&su[j]*i<MAX;j++)
16         {
17             isprime[su[j]*i]=0;//筛掉小于等于i的素数和i的积构成的合数
18         }
19     }
20 }
21 int main()
22 {
23     prime();
24     for(long long i=1;i<cnt;i++)
25         printf("%d  ",su[i]);
26     return 0;
27 }
View Code

2.2 米勒罗宾素数测试

 1 //https://blog.csdn.net/u013654696/article/details/40056179
 2 // 18位素数:154590409516822759
 3 // 19位素数:2305843009213693951 (梅森素数)
 4 // 19位素数:4384957924686954497
 5 LL prime[6] = {2, 3, 5, 233, 331};
 6 LL qmul(LL x, LL y, LL mod) { // 乘法防止溢出, 如果p * p不爆LL的话可以直接乘; O(1)乘法或者转化成二进制加法
 7 
 8 
 9     return (x * y - (long long)(x / (long double)mod * y + 1e-3) *mod + mod) % mod;
10     /*
11     LL ret = 0;
12     while(y) {
13         if(y & 1)
14             ret = (ret + x) % mod;
15         x = x * 2 % mod;
16         y >>= 1;
17     }
18     return ret;
19     */
20 }
21 LL qpow(LL a, LL n, LL mod) {
22     LL ret = 1;
23     while(n) {
24         if(n & 1) ret = qmul(ret, a, mod);
25         a = qmul(a, a, mod);
26         n >>= 1;
27     }
28     return ret;
29 }
30 bool Miller_Rabin(LL p) {
31     if(p < 2) return 0;
32     if(p != 2 && p % 2 == 0) return 0;
33     LL s = p - 1;
34     while(! (s & 1)) s >>= 1;
35     for(int i = 0; i < 5; ++i) {
36         if(p == prime[i]) return 1;
37         LL t = s, m = qpow(prime[i], s, p);
38         while(t != p - 1 && m != 1 && m != p - 1) {
39             m = qmul(m, m, p);
40             t <<= 1;
41         }
42         if(m != p - 1 && !(t & 1)) return 0;
43     }
44     return 1;
45 }
View Code

三.数学相关

3.1 扩展欧几里得算法

 1 int exgcd(int a,int b,int &x,int &y)
 2 {
 3     if(b==0)
 4     {
 5         x=1;
 6         y=0;
 7         return a;
 8     }
 9     int r=exgcd(b,a%b,x,y);
10     int t=x;
11     x=y;
12     y=t-a/b*y;
13     return r;
14 }
View Code

四.技巧

4.1 imos累积和法

 1 //http://www.hankcs.com/program/algorithm/imos_method.html
 2 //算法用于计算二维平面最大高度点,原理左上右下标1,左下右上标-1,累加求最大。
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <bits/stdc++.h>
 6 using namespace std;
 7 #define  W  6
 8 #define  H  6
 9 #define  N  4
10 // 左下角坐标
11 int B[N] = {3,4,3,5,};
12 int C[N] = {0,1,2,2,};
13 // 右上角坐标
14 int A[N] = {0,3,2,2,};
15 int D[N] = {3,2,3,5,};
16 // 地图上的分布结果
17 int tiles[H][W];
18 
19 ///////////////////////////SubMain//////////////////////////////////
20 int main(int argc, char *argv[])
21 {
22     memset(tiles, 0, sizeof(tiles));
23     // 影响力计算 (图 3)
24     for (int i = 0; i < N; i++)
25     {
26         tiles[C[i]][A[i]]++;
27         tiles[C[i]][B[i]]--;
28         tiles[D[i]][A[i]]--;
29         tiles[D[i]][B[i]]++;
30     }
31     // 横向累积和 (图 4, 5)
32     for (int y = 0; y < H; y++)
33     {
34         for (int x = 1; x < W; x++)
35         {
36             tiles[y][x] += tiles[y][x - 1];
37         }
38     }
39     // 纵向累积和 (图 6, 7)
40     for (int y = 1; y < H; y++)
41     {
42         for (int x = 0; x < W; x++)
43         {
44             tiles[y][x] += tiles[y - 1][x];
45         }
46     }
47 
48     cout << *max_element(tiles[0], tiles[0] + H * W) << endl;
49     system("pause");
50     return 0;
51 }
52 ///////////////////////////End Sub//////////////////////////////////
View Code

4.2 坐标离散化

  1 //http://www.hankcs.com/program/algorithm/aoj-0531-paint-color.html
  2 #include<iostream>
  3 #include<vector>
  4 #include<algorithm>
  5 #include<queue>
  6 #include <cstring>
  7 #define MAX_N 1000 + 16
  8  
  9 using namespace std;
 10  
 11 int N, H, W;
 12 int X1[MAX_N], X2[MAX_N], Y1[MAX_N], Y2[MAX_N];
 13 int fld[2 * MAX_N][2 * MAX_N], // 填充遍历用,代表坐标(i, j)处是否空白(压缩后)
 14 dx[4] = { 1, -1, 0, 0 }, dy[4] = { 0, 0, 1, -1 };
 15 
 16 // 压缩坐标,将坐标的值变成“这是第几种值”,返回一共有几种坐标
 17 int compress(int *x1, int *x2, int w)
 18 {
 19     vector<int>xs;
 20  
 21     for (int i = 0; i < N; ++i)
 22     {
 23         int tx1 = x1[i], tx2 = x2[i];
 24         if (1 <= tx1 && tx1 < w) xs.push_back(tx1);
 25         if (1 <= tx2 && tx2 < w) xs.push_back(tx2);
 26     }
 27     xs.push_back(0);
 28     xs.push_back(w);
 29     sort(xs.begin(), xs.end());
 30     xs.erase(unique(xs.begin(), xs.end()), xs.end());
 31     for (int i = 0; i < N; ++i)
 32     {
 33         x1[i] = find(xs.begin(), xs.end(), x1[i]) - xs.begin();
 34         x2[i] = find(xs.begin(), xs.end(), x2[i]) - xs.begin();
 35     }
 36     return xs.size() - 1;
 37 }
 38  
 39 int bfs()
 40 {
 41     int ans = 0;
 42     for (int i = 0; i < H; ++i)
 43     {
 44         for (int j = 0; j < W; ++j)
 45         {
 46             if (fld[i][j]) continue;
 47             ++ans;
 48             queue<pair<int, int> >que;
 49             que.push(make_pair(j, i));
 50             while (!que.empty())
 51             {
 52                 int nx = que.front().first, ny = que.front().second;
 53                 que.pop();
 54  
 55                 for (int i = 0; i < 4; ++i)
 56                 {
 57                     int tx = nx + dx[i], ty = ny + dy[i];
 58                     if (tx < 0 || W < tx || ty < 0 || H< ty || fld[ty][tx] > 0) continue;
 59                     que.push(make_pair(tx, ty));
 60                     fld[ty][tx] = 1;
 61                 }
 62             }
 63         }
 64     }
 65     return ans;
 66 }
 67  
 68 ///////////////////////////SubMain//////////////////////////////////
 69 int main(int argc, char *argv[])
 70 {
 71     while (cin >> W >> H, W | H)
 72     {
 73         cin >> N;
 74         for (int i = 0; i < N; ++i)
 75         {
 76             cin >> X1[i] >> Y1[i] >> X2[i] >> Y2[i];
 77         }
 78  
 79         memset(fld, 0, sizeof(fld));
 80  
 81         W = compress(X1, X2, W);
 82         H = compress(Y1, Y2, H);
 83  
 84         // imos-法
 85         for (int i = 0; i < N; i++)
 86         {
 87             fld[Y1[i]][X1[i]]++;
 88             fld[Y1[i]][X2[i]]--;
 89             fld[Y2[i]][X1[i]]--;
 90             fld[Y2[i]][X2[i]]++;
 91         }
 92         // 横向累积
 93         for (int i = 0; i < H; i++)
 94         {
 95             for (int j = 1; j < W; j++)
 96             {
 97                 fld[i][j] += fld[i][j - 1];
 98             }
 99         }
100         // 纵向累积
101         for (int i = 1; i < H; i++)
102         {
103             for (int j = 0; j < W; j++)
104             {
105                 fld[i][j] += fld[i - 1][j];
106             }
107         }// 累积完后,fld中非0部分表示有挡板
108         cout << bfs() << endl;
109     }
110     return 0;
111 }
112 ///////////////////////////End Sub//////////////////////////////////
View Code

五.数据结构

5.1 并查集

 1 //https://blog.csdn.net/u013486414/article/details/38682057
 2 const int MAXSIZE = 500;
 3 int uset[MAXSIZE];
 4 void makeSet(int size)
 5 {
 6     for(int i = 0; i < size; i++) uset[i] = -1;
 7 }
 8 int find(int x)
 9 {
10     if (uset[x] < 0) return x;
11     uset[x] = find(uset[x]);
12     return uset[x];
13 }
14 
15 int find(int x)
16 {
17     int p = x, t;
18     while (uset[p] >= 0) p = uset[p];
19     while (x != p)
20     {
21         t = uset[x];
22         uset[x] = p;
23         x = t;
24     }
25     return x;
26 }
27 void unionSet(int x, int y)
28 {
29     if ((x = find(x)) == (y = find(y))) return;
30     if (uset[x] < uset[y])
31     {
32         uset[x] += uset[y];
33         uset[y] = x;
34     }
35     else
36     {
37         uset[y] += uset[x];
38         uset[x] = y;
39     }
40 }
View Code

猜你喜欢

转载自www.cnblogs.com/bestefforts/p/8993859.html
今日推荐