模板集合
模板集合
数据结构:
线段树:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define ll long long 4 #define N 100010 5 using namespace std; 6 7 ll n, m, a[N]; 8 9 struct xcj{ 10 ll l, r, value, add; 11 #define l(x) t[x].l 12 #define r(x) t[x].r 13 #define sum(x) t[x].value 14 #define add(x) t[x].add 15 } t[N * 4]; 16 17 inline ll read(){ 18 ll s = 0, w = 1; 19 char ch = getchar(); 20 while (ch < '0' || ch > '9'){ 21 if (ch == '-') w *= -1; 22 ch = getchar(); 23 } 24 while (ch >= '0' && ch <= '9'){ 25 s = s * 10 + ch - '0'; 26 ch = getchar(); 27 } 28 return s * w; 29 } 30 31 inline void spread(ll p){ 32 if (add(p)){ 33 sum(p * 2) += add(p) * (r(p * 2) - l(p * 2) + 1); 34 sum(p * 2 + 1) += add(p) * (r(p * 2 + 1) - l(p * 2 + 1) + 1); 35 add(p * 2) += add(p); 36 add(p * 2 + 1) += add(p); 37 add(p) = 0; 38 } 39 } 40 41 inline void change(ll p, ll l, ll r, ll v){ 42 if (l <= l(p) && r >= r(p)){ 43 sum(p) += v * (r(p) - l(p) + 1); 44 add(p) += v; 45 return ; 46 } 47 spread(p); 48 ll mid = (l(p) + r(p)) / 2; 49 if (l <= mid) change(p * 2, l, r, v); 50 if (r > mid) change(p * 2 + 1, l, r, v); 51 sum(p) = sum(p * 2) + sum(p * 2 + 1); 52 } 53 54 inline ll ask(ll p, ll l, ll r){ 55 if (l <= l(p) && r >= r(p)) return sum(p); 56 spread(p); 57 ll mid = (l(p) + r(p)) / 2, valu = 0; 58 if (l <= mid) valu += ask(p * 2, l, r); 59 if (r > mid) valu += ask(p * 2 + 1, l, r); 60 return valu; 61 } 62 63 inline void build(ll p, ll l, ll r){ 64 l(p) = l, r(p) = r; 65 if (l == r){ 66 sum(p) = a[l]; 67 return ; 68 } 69 ll mid = (l + r) / 2; 70 build(p * 2, l, mid); 71 build(p * 2 + 1, mid + 1, r); 72 sum(p) = sum(p * 2) + sum(p * 2 + 1); 73 } 74 75 inline void init(){ 76 n = read(), m = read(); 77 REP(i, 1, n) a[i] = read(); 78 } 79 80 inline void work(){ 81 init(); 82 build(1, 1, n); 83 while (m--){ 84 ll lyj = read(), l = read(), r = read(); 85 if (lyj == 1){ 86 ll val = read(); 87 change(1, l, r, val); 88 } else printf("%lld\n", ask(1, l, r)); 89 } 90 } 91 92 int main(){ 93 work(); 94 return 0; 95 }
树状数组:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for(int i = a; i <= b; ++i) 3 using namespace std; 4 5 int n, m, a[500005], c[500005], k, x, y, z; 6 7 inline int read(){ 8 int s = 0, w = 1; 9 char ch = getchar(); 10 while (ch < '0' || ch > '9'){ 11 if (ch == '-') w = -1; 12 ch = getchar(); 13 } 14 while (ch >= '0' && ch <= '9'){ 15 s = (s << 1) + (s << 3) + ch - '0'; 16 ch = getchar(); 17 } 18 return s * w; 19 } 20 21 int lowbit(int n){ 22 return n & (-n); 23 } 24 25 void update(int x, int y){ 26 for ( ; x <= n; x += lowbit(x)) c[x] += y; 27 } 28 29 int sum(int x){ 30 int ans = 0; 31 for ( ; x; x -= lowbit(x)) ans += c[x]; 32 return ans; 33 } 34 35 int main(){ 36 n = read(), m = read(); 37 REP(i, 1, n) a[i] = read(); 38 REP(i, 1, m){ 39 k = read(); 40 if (k == 1){ 41 x = read(), y = read(), z = read(); 42 update(x, z); 43 update(y + 1, -z); 44 } else { 45 x = read(); 46 printf("%d\n", a[x] + sum(x)); 47 } 48 } 49 return 0; 50 }
堆:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for(int i = a; i <= b; ++i) 3 #define S(n) scanf("%d", &n) 4 using namespace std; 5 6 priority_queue< int, vector<int>, greater<int> > q; 7 8 int n, a, x; 9 10 int main(){ 11 S(n); 12 REP(i, 1, n){ 13 S(a); 14 if (a == 1){ 15 S(x); 16 q.push(x); 17 } 18 else if (a == 2) printf("%d\n", q.top()); 19 else q.pop(); 20 } 21 return 0; 22 }
单调栈:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define PER(i, a, b) for (long long i = a; i >= b; --i) 4 #define ll long long 5 #define N 3000010 6 using namespace std; 7 8 ll n, tot, a[N], s[N], ans[N]; 9 10 inline ll read(){ 11 ll s = 0, w = 1; 12 char ch = getchar(); 13 while (ch < '0' || ch > '9'){ 14 if (ch == '-') w *= -1; 15 ch = getchar(); 16 } 17 while (ch >= '0' && ch <= '9'){ 18 s = s * 10 + ch - '0'; 19 ch = getchar(); 20 } 21 return s * w; 22 } 23 24 inline void init(){ 25 n = read(); 26 REP(i, 1, n) a[i] = read(); 27 } 28 29 inline void work(){ 30 init(); 31 PER(i, n, 1){ 32 while (tot > 0 && a[s[tot]] <= a[i]) tot--; 33 if (tot == 0) ans[i] = 0; 34 else ans[i] = s[tot]; 35 s[++tot] = i; 36 } 37 REP(i, 1, n) printf("%lld ", ans[i]); 38 puts(""); 39 } 40 41 int main(){ 42 work(); 43 return 0; 44 }
单调队列:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define ll long long 4 #define N 1000010 5 using namespace std; 6 7 ll n, k, a[N], q[N], p[N]; 8 9 inline ll read(){ 10 ll s = 0, w = 1; 11 char ch = getchar(); 12 while (ch < '0' || ch > '9'){ 13 if (ch == '-') w *= -1; 14 ch = getchar(); 15 } 16 while (ch >= '0' && ch <= '9'){ 17 s = s * 10 + ch - '0'; 18 ch = getchar(); 19 } 20 return s * w; 21 } 22 23 inline void init(){ 24 n = read(), k = read(); 25 REP(i, 1, n) a[i] = read(); 26 } 27 28 inline void xcj(){ //min 29 ll head = 1, tail = 0; 30 REP(i, 1, n){ 31 while (head <= tail && q[tail] >= a[i]) tail--; 32 q[++tail] = a[i], p[tail] = i; 33 while (p[head] <= i - k) head++; 34 if (i >= k) printf("%lld ", q[head]); 35 } 36 puts(""); 37 } 38 39 inline void lyj(){ //max 40 ll head = 1, tail = 0; 41 REP(i, 1, n){ 42 while (head <= tail && q[tail] <= a[i]) tail--; 43 q[++tail] = a[i], p[tail] = i; 44 while (p[head] <= i - k) head++; 45 if (i >= k) printf("%lld ", q[head]); 46 } 47 puts(""); 48 } 49 50 inline void work(){ 51 init(); 52 xcj(); 53 lyj(); 54 } 55 56 int main(){ 57 work(); 58 return 0; 59 }
并查集:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (int i = a; i <= b; ++i) 3 #define PER(i, a, b) for (int i = a; i >= b; --i) 4 #define N 100010 5 using namespace std; 6 7 int fa[N], size[N], n, m; 8 9 int find(int x){ 10 return x == fa[x] ? x : fa[x] = find(fa[x]); 11 } 12 13 void merge(int x, int y){ 14 int xx = find(x), yy = find(y); 15 if (size[xx] < size[yy]) fa[xx] = yy, size[yy] += size[xx]; 16 else fa[yy] = xx, size[xx] += size[yy]; 17 } 18 19 inline int read(){ 20 int s = 0, w = 1; 21 char ch = getchar(); 22 while (ch < '0' || ch > '9'){ 23 if (ch == '-') w = -1; 24 ch = getchar(); 25 } 26 while (ch >= '0' && ch <= '9'){ 27 s = s * 10 + ch - '0'; 28 ch = getchar(); 29 } 30 return s * w; 31 } 32 33 int main(){ 34 n = read(), m = read(); 35 REP(i, 1, n) fa[i] = i, size[i] = 1; 36 while (m--){ 37 int opt = read(), x = read(), y = read(); 38 if (opt == 1) merge(x, y); 39 else { 40 int xx = find(x), yy = find(y); 41 if (xx == yy) puts("Y"); 42 else puts("N"); 43 } 44 } 45 return 0; 46 }
ST表:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (int i = a; i <= b; ++i) 3 #define N 1000010 4 #define Logn 20 5 using namespace std; 6 7 int n, m, x, y, Log[N], f[N][25], a[N]; 8 9 inline int read(){ 10 int s = 0, w = 1; 11 char ch = getchar(); 12 while (ch < '0' || ch > '9'){ 13 if (ch == '-') w = -1; 14 ch = getchar(); 15 } 16 while (ch >= '0' && ch <= '9'){ 17 s = s * 10 + ch - '0'; 18 ch = getchar(); 19 } 20 return s * w; 21 } 22 23 void init(){ 24 n = read(), m = read(); 25 REP(i, 1, n) a[i] = read(); 26 } 27 28 void work(){ 29 init(); 30 Log[0] = -1;// 31 REP(i, 1, n) 32 f[i][0] = a[i], Log[i] = Log[i >> 1] + 1; 33 REP(j, 1, Logn) 34 for (int i = 1; i + (1 << j) - 1 <= n; ++i) 35 f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]); 36 while (m--){ 37 x = read(), y = read(); 38 printf("%d\n", max(f[x][Log[y - x + 1]], f[y - (1 << Log[y - x + 1]) + 1][Log[y - x + 1]])); 39 } 40 } 41 42 int main(){ 43 work(); 44 return 0; 45 }
图论:
单源最短路径:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (int i = a; i <= b; ++i) 3 #define N 100010 4 #define M 200010 5 using namespace std; 6 7 int n, m, s, tot, head[N], ver[M], edge[M], Next[M], d[N]; 8 bool v[N]; 9 10 priority_queue < pair < int, int > > q; 11 12 inline int read(){ 13 int s = 0, w = 1; 14 char ch = getchar(); 15 while (ch < '0' || ch > '9'){ 16 if (ch == '-') w *= -1; 17 ch = getchar(); 18 } 19 while (ch >= '0' && ch <= '9'){ 20 s = s * 10 + ch - '0'; 21 ch = getchar(); 22 } 23 return s * w; 24 } 25 26 void add(int x, int y, int z){ 27 ver[++tot] = y; 28 edge[tot] = z; 29 Next[tot] = head[x]; 30 head[x] = tot; 31 } 32 33 void dijkstra(int s){ 34 memset(d, 0x3f, sizeof(d)); 35 memset(v, 0, sizeof(v)); 36 d[s] = 0; 37 q.push(make_pair(0, s)); 38 while (q.size()){ 39 int x = q.top().second; 40 q.pop(); 41 if (v[x]) continue; 42 v[x] = 1; 43 for (int i = head[x]; i; i = Next[i]){ 44 int y = ver[i], z = edge[i]; 45 if (d[y] > d[x] + z){ 46 d[y] = d[x] + z; 47 q.push(make_pair(-d[y], y)); 48 } 49 } 50 } 51 } 52 53 int main(){ 54 n = read(), m = read(), s = read(); 55 REP(i, 1, m){ 56 int x, y, z; 57 x = read(), y = read(), z = read(); 58 add(x, y, z); 59 } 60 dijkstra(s); 61 REP(i, 1, n){ 62 if (d[i] == 1061109567) d[i] = INT_MAX; 63 printf("%d%c", d[i], i == n ? '\n' : ' '); 64 } 65 return 0; 66 }
最小生成树:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (int i = a; i <= b; ++i) 3 #define N 200010 4 using namespace std; 5 6 int n, m, prt[N], ans, bj = 1, f1, f2, k; 7 8 inline int read(){ 9 int s = 0, w = 1; 10 char ch = getchar(); 11 while (ch < '0' || ch > '9'){ 12 if (ch == '-') w = -1; 13 ch = getchar(); 14 } 15 while (ch >= '0' && ch <= '9'){ 16 s = s * 10 + ch - '0'; 17 ch = getchar(); 18 } 19 return s * w; 20 } 21 22 struct Edge{ 23 int x, y, z; 24 } a[N]; 25 26 bool cmp(const Edge &x, const Edge &y){ 27 return x.z < y.z; 28 } 29 30 int getfather(int x){ 31 if (prt[x] == x) return x; 32 return prt[x] = getfather(prt[x]); 33 } 34 35 void init(){ 36 n = read(), m = read(); 37 REP(i, 1, m) 38 a[i].x = read(), a[i].y = read(), a[i].z = read(); 39 sort(a + 1, a + m + 1, cmp); 40 } 41 42 void Kruskal(){ 43 REP(i, 1, n) 44 prt[i] = i; 45 REP(i, 1, m){ 46 f1 = getfather(a[i].x); 47 f2 = getfather(a[i].y); 48 if (f1 != f2){ 49 ans = ans + a[i].z; 50 prt[f1] = f2; 51 k++; 52 if (k == n - 1) break; 53 } 54 } 55 if (k < n - 1){ 56 printf("orz\n"); 57 bj = 0; 58 return ; 59 } 60 } 61 62 void work(){ 63 init(); 64 bj = 1; 65 Kruskal(); 66 if (bj) printf("%d\n", ans); 67 } 68 69 int main(){ 70 work(); 71 return 0; 72 }
动态规划:
01背包:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define PER(i, a, b) for (long long i = a; i >= b; --i) 4 #define minclr(a) memset((a), 0xcf, sizeof(a)) 5 #define ll long long 6 #define N 1000010 7 using namespace std; 8 9 ll n, m, ans, v[N], w[N], f[N]; 10 11 inline ll read(){ 12 ll s = 0, w = 1; 13 char ch = getchar(); 14 while (ch < '0' || ch > '9'){ 15 if (ch == '-') w *= -1; 16 ch = getchar(); 17 } 18 while (ch >= '0' && ch <= '9'){ 19 s = s * 10 + ch - '0'; 20 ch = getchar(); 21 } 22 return s * w; 23 } 24 25 int main(){ 26 n = read(), m = read(); 27 REP(i, 1, n) v[i] = read(), w[i] = read(); 28 minclr(f); 29 f[0] = 0; 30 REP(i, 1, n) 31 PER(j, m, v[i]) 32 f[j] = max(f[j], f[j - v[i]] + w[i]); 33 REP(i, 0, m) ans = max(ans, f[i]); 34 printf("%lld\n", ans); 35 return 0; 36 }
多重背包:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define PER(i, a, b) for (long long i = a; i >= b; --i) 4 #define minclr(a) memset((a), 0xcf, sizeof(a)) 5 #define ll long long 6 #define N 1000010 7 using namespace std; 8 9 ll n, m, ans, v[N], w[N], c[N], f[N]; 10 11 inline ll read(){ 12 ll s = 0, w = 1; 13 char ch = getchar(); 14 while (ch < '0' || ch > '9'){ 15 if (ch == '-') w *= -1; 16 ch = getchar(); 17 } 18 while (ch >= '0' && ch <= '9'){ 19 s = s * 10 + ch - '0'; 20 ch = getchar(); 21 } 22 return s * w; 23 } 24 25 int main(){ 26 n = read(), m = read(); 27 REP(i, 1, n) v[i] = read(), w[i] = read(), c[i] = read(); 28 minclr(f); 29 f[0] = 0; 30 REP(i, 1, n) 31 REP(j, 1, c[i]) 32 PER(k, m, v[i]) 33 f[k] = max(f[k], f[k - v[i]] + w[i]); 34 REP(i, 0, m) ans = max(ans, f[i]); 35 printf("%lld\n", ans); 36 return 0; 37 }
完全背包:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define minclr(a) memset((a), 0xcf, sizeof(a)) 4 #define ll long long 5 #define N 1000010 6 using namespace std; 7 8 ll n, m, ans, v[N], w[N], f[N]; 9 10 inline ll read(){ 11 ll s = 0, w = 1; 12 char ch = getchar(); 13 while (ch < '0' || ch > '9'){ 14 if (ch == '-') w *= -1; 15 ch = getchar(); 16 } 17 while (ch >= '0' && ch <= '9'){ 18 s = s * 10 + ch - '0'; 19 ch = getchar(); 20 } 21 return s * w; 22 } 23 24 int main(){ 25 n = read(), m = read(); 26 REP(i, 1, n) v[i] = read(), w[i] = read(); 27 minclr(f); 28 f[0] = 0; 29 REP(i, 1, n) 30 REP(j, v[i], m) 31 f[j] = max(f[j], f[j - v[i]] + w[i]); 32 REP(i, 0, m) ans = max(ans, f[i]); 33 printf("%lld\n", ans); 34 return 0; 35 }
分组背包:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define PER(i, a, b) for (long long i = a; i >= b; --i) 4 #define minclr(a) memset((a), 0xcf, sizeof(a)) 5 #define ll long long 6 #define N 100010 7 #define M 1010 8 using namespace std; 9 10 ll n, m, ans, c[N], f[N], v[N][M], w[N][M]; 11 12 inline ll read(){ 13 ll s = 0, w = 1; 14 char ch = getchar(); 15 while (ch < '0' || ch > '9'){ 16 if (ch == '-') w *= -1; 17 ch = getchar(); 18 } 19 while (ch >= '0' && ch <= '9'){ 20 s = s * 10 + ch - '0'; 21 ch = getchar(); 22 } 23 return s * w; 24 } 25 26 int main(){ 27 n = read(), m = read(); 28 REP(i, 1, n){ 29 c[i] = read(); 30 REP(j, 1, c[i]) v[i][j] = read(), w[i][j] = read(); 31 } 32 minclr(f); 33 f[0] = 0; 34 REP(i, 1, n) 35 PER(j, m, 0) 36 REP(k, 1, c[i]) 37 if (j >= v[i][k]) f[j] = max(f[j], f[j - v[i][k]] + w[i][k]); 38 REP(i, 0, m) ans = max(ans, f[i]); 39 printf("%lld\n", ans); 40 return 0; 41 }
数学知识:
快速幂:
1 #include <bits/stdc++.h> 2 #define O(i, a, b) for(int i = a; i <= b; ++i) 3 #define R(i, a, b) for(int i = a; i >= b; --i) 4 #define S(n) scanf("%d", &n) 5 using namespace std; 6 7 int n, b, p; 8 9 int qpow(int a, int b, int p){ 10 int ans = 1 % p; 11 for (; b; b >>= 1){ 12 if (b & 1) ans = (long long)ans * a % p; 13 a = (long long)a * a % p; 14 } 15 return ans; 16 } 17 18 int main(){ 19 S(n), S(b), S(p); 20 printf ("%d^%d mod %d=%d", n, b, p, qpow(n, b, p)); 21 return 0; 22 }
线性筛素数:
1 #include <bits/stdc++.h> 2 #define O(i, a, b) for(int i = a; i <= b; ++i) 3 #define R(i, a, b) for(int i = a; i >= b; --i) 4 #define S(n) scanf("%d", &n) 5 using namespace std; 6 7 int n, m, a, pd[10000005], v[10000005], k; 8 9 void pss(int n){ 10 memset(v, 0, sizeof(v)); 11 O(i, 2, n){ 12 if (!v[i]){ 13 v[i] = i; 14 pd[++k] = i; 15 } 16 O(j, 1, k){ 17 if (pd[j] > v[i] || pd[j] > n / i) break; 18 v[i * pd[j]] = pd[j]; 19 } 20 } 21 } 22 23 int main(){ 24 S(n), S(m); 25 pss(n); 26 O(i, 1, m){ 27 int f = 0; 28 S(a); 29 if (v[a] == a) puts("Yes"); 30 else puts("No"); 31 } 32 return 0; 33 }
字符串:
KMP字符串匹配:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (long long i = a; i <= b; ++i) 3 #define ll long long 4 #define N 1000010 5 using namespace std; 6 7 ll n, m, f[N], ans[N], next[N]; 8 char a[N], b[N]; 9 10 int main(){ 11 scanf("%s%s", b + 1, a + 1); 12 n = strlen(a + 1), m = strlen(b + 1); 13 next[1] = 0; 14 for (ll i = 2, j = 0; i <= n; ++i){ 15 while (j > 0 && a[i] != a[j + 1]) j = next[j]; 16 if (a[i] == a[j + 1]) j++; 17 next[i] = j; 18 } 19 for (ll i = 1, j = 0; i <= m; ++i){ 20 bool flag = 0; 21 while (j > 0 && (j == n || b[i] != a[j + 1])) j = next[j]; 22 if (b[i] == a[j + 1]) j++, flag = 1; 23 f[i] = j; 24 ans[i] = i - j + 1; 25 } 26 REP(i, 1, m) 27 if (f[i] == n) printf("%lld\n", ans[i]); 28 REP(i, 1, n) printf("%lld%c", next[i], i == n ? '\n' : ' '); 29 return 0; 30 }
字符串哈希:
1 #include <bits/stdc++.h> 2 #define REP(i, a, b) for (int i = a; i <= b; ++i) 3 #define PER(i, a, b) for (int i = a; i >= b; --i) 4 using namespace std; 5 6 map < string, int > mps; 7 string s; 8 int n, ans; 9 10 inline int read(){ 11 int s = 0, w = 1; 12 char ch = getchar(); 13 while (ch < '0' || ch > '9'){ 14 if (ch == '-') w = -1; 15 ch = getchar(); 16 } 17 while (ch >= '0' && ch <= '9'){ 18 s = s * 10 + ch - '0'; 19 ch = getchar(); 20 } 21 return s * w; 22 } 23 24 int main(){ 25 n = read(); 26 REP(i, 1, n){ 27 cin >> s; 28 if (mps[s] == 0) ans++; 29 mps[s]++; 30 } 31 printf("%d\n", ans); 32 return 0; 33 }
浙公网安备 33010602011771号