东拼西凑的模板·持续更新中
Posted Best_Efforts
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了东拼西凑的模板·持续更新中相关的知识,希望对你有一定的参考价值。
一.常用算法(应该不需要用到模板的那种常用)
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 }
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 }
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 }
三.数学相关
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 }
四.技巧
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//////////////////////////////////
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//////////////////////////////////
五.数据结构
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 }
以上是关于东拼西凑的模板·持续更新中的主要内容,如果未能解决你的问题,请参考以下文章
如何通过单击适配器类中代码的项目中的删除按钮来删除列表视图中的项目后重新加载片段?