- 数学有关的东西
- gcd
- exgcd
- 快速幂
- 欧拉筛法
- 最长不上升子序列
- 高精度加法读入输出
- 矩阵快速幂
- 数据结构
- 算法
- 最小生成树
- 匈牙利算法
- SPFA
- 堆dijkstra
- KMP
- 倍增LCA
- Tarjan求环
- 归并排序
- 网络流dinic
- 字符串hash
数学有关的东西
gcd:
可以交在传送门洛谷2152拿完20分就跑23333(正解需要高精+一堆处理)
#include <cstdio>#include <cstring>#include <algorithm>long long a, b;long long gcd(long long a, long long b) { if (b == 0) return (a); return (gcd(b, a % b));}int main () { scanf("%lld %lld", &a, &b); printf("%lld", gcd(a, b)); return 0;}
exgcd:
传送门洛谷1082
#include <cstdio>#include <cstring>#include <algorithm>int a, b, x, y;void exgcd(int a, int b, int &x, int &y) { if (b == 0) { x = 1; y = 0; return; } exgcd(b, a % b, x, y); int t = x; x = y; y = t - a / b * y;}int main () { scanf("%d %d", &a, &b); exgcd(a, b, x, y); x = ((x % b) + b ) % b; printf("%d", x); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
快速幂:
传送门洛谷1226
#include <cstdio>#include <cstring>#include <algorithm>long long b, p, k;long long qpow(long long base, long long v, long long mod) { long long ans = 1; while (v > 0) { if (v & 1) ans = (ans * base) % mod; base = (base * base) % mod; v = v >> 1; } return (ans);}int main () { scanf("%lld %lld %lld", &b, &p, &k); printf("%lld^%lld mod %lld=%lld", b, p, k, qpow(b, p, k)); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
欧拉筛法:
传送门洛谷3383
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 10000000 + 5000;int n, m;int prime[maxn], isp[maxn];int ptot = 0;int x;int main () { scanf("%d %d", &n, &m); for (int i = 2; i <= n; i++) isp[i] = 1; for (int i = 2; i <= n; i++) { if (isp[i]) { ptot++; prime[ptot] = i; } long long k; for (int j = 1; j <= ptot && (k = 1ll * prime[j] * i) <= n; j++) { isp[k] = 0; if (!(i % prime[j])) break; } } for (int i = 1; i <= m; i++) { scanf("%d", &x); if (isp[x]) printf("Yes\n"); else printf("No\n"); } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
最长不上升子序列:
传送门洛谷2757
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 300000 + 500;int n;int a[maxn];int d[maxn];int len = 0;int x;int ans;int main () { d[0] = 0x7fffffff; n = 1; while (scanf("%d", &a[n]) == 1) { if (a[n] <= d[len]) { len++; d[len] = a[n]; } else { int l = 0, r = len; while (l <= r) { int mid = (l + r) >> 1; if (d[mid] >= a[n]) { l = mid + 1; ans = mid; } else { r = mid - 1; } } d[ans+1] = a[n]; } n++; } printf("%d\n", len); memset(d, 0, sizeof(d)); n--; len = 0; for (int i = 1; i <= n; i++) { if (a[i] > d[len]) { len++; d[len] = a[i]; } else { int l = 0, r = len; while (l <= r) { int mid = (l + r) >> 1; if (d[mid] < a[i]) { l = mid + 1; ans = mid; } else { r = mid - 1; } } d[ans+1] = a[i]; } } printf("%d", len); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
高精度加法,读入,输出:
传送门洛谷1601
注意进位时要用+=
#include <cstdio>#include <cstring>#include <algorithm>int tt[1000];struct bigint { int num; int a[1000]; void print() { for (int j = num; j >= 1; j--) { printf("%d", a[j]); } printf("\n"); } void readint() { memset(tt, 0, sizeof(tt)); char c = getchar(); num = 0; while (c < '0' || c > '9') c = getchar(); while (c >= '0' && c <= '9') { num++; tt[num] = c - '0'; c = getchar(); } for (int i = 1; i <= num; i++) a[i] = tt[num - i + 1]; } void clear0() { num = 0; memset(a, 0, sizeof(a)); } void clear1() { num = 1; memset(a, 0, sizeof(a)); a[1] = 1; }};bigint aa, bb;bigint cc;bigint operator + (bigint xx, bigint yy) { bigint cc; cc.clear0(); cc.num = std :: max(xx.num, yy.num); for (int i = 1; i <= cc.num; i++) { cc.a[i] += xx.a[i] + yy.a[i]; if (cc.a[i] >= 10) { cc.a[i+1] += cc.a[i] / 10; cc.a[i] = cc.a[i] % 10; } } if (cc.a[cc.num + 1] == 0) return (cc); cc.num++; while (cc.a[cc.num] >= 10) { cc.a[cc.num+1] += cc.a[cc.num] / 10; cc.a[cc.num] = cc.a[cc.num] % 10; } return (cc);}int main () { aa.readint(); bb.readint(); cc = aa + bb; cc.print(); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
矩阵快速幂:
传送门洛谷3390
手一抖就把乘号打成了加号
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 110;const long long mod = 1e9 + 7;int n;struct data { long long a[maxn][maxn]; void clear0(void) { memset(a, 0, sizeof(a)); } void clear1(void) { memset(a, 0, sizeof(a)); for (int i = 1; i <= n; i++) a[i][i] = 1; } void print() { for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) printf("%d ", a[i][j]); printf("\n"); } }};long long k;data aa;data ans;data operator * (data xx, data yy) { data cc; cc.clear0(); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) for (int k = 1; k <= n; k++) cc.a[i][j] = (cc.a[i][j] + xx.a[i][k] * yy.a[k][j]) % mod; return (cc);}data qpow(data aa, long long v, long long mod) { data ans; ans.clear1(); while (v > 0) { if (v & 1) ans = ans * aa; v = v >> 1; aa = aa * aa; } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) ans.a[i][j] %= mod; return ans;}int main () { scanf("%d %lld", &n, &k); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { scanf("%d", &aa.a[i][j]); aa.a[i][j] %= mod; } ans = qpow(aa, k, mod); ans.print(); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
数据结构:
树状数组:
传送门洛谷3374
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 550000;int c[maxn];int n, m;int x;int odd, y;inline int lowbit(int x) { return (x & (-x));}void change(int x, int z) { while (x <= n) { c[x] += z; x += lowbit(x); }}long long xfind(int x) { long long ans = 0; while (x > 0) { ans += c[x]; x -= lowbit(x); } return (ans);}int main () { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &x); change(i, x); } for (int i = 1; i <= m; i++) { scanf("%d %d %d", &odd, &x, &y); if (odd == 1) { change(x, y); } else { printf("%lld\n", xfind(y) - xfind(x-1)); } } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
线段树:
传送门洛谷3372
手抖数组没开三倍,,
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 110000;struct data { int l, r; long long sum; long long lazy;};data p[maxn * 3];int a[maxn];int n, m;int od, x, y, z;void build(int x, int l, int r) { p[x].l = l; p[x].r = r; if (p[x].l == p[x].r) { p[x].sum = a[l]; return; } int mid = (l + r) >> 1; build(2 * x, l, mid); build(2 * x + 1, mid + 1, r); p[x].sum = p[2 * x].sum + p[2 * x + 1].sum;}void update(int x) { p[x].sum += p[x].lazy * (p[x].r - p[x].l + 1); if (p[x].l == p[x].r) { p[x].lazy = 0; return; } p[2 * x].lazy += p[x].lazy; p[2 * x + 1].lazy += p[x].lazy; p[x].lazy = 0;}void change(int x, int l, int r, int z) { if (p[x].l == l && p[x].r == r) { p[x].lazy += z; return; } if (p[x].lazy) update(x); int mid = (p[x].l + p[x].r) >> 1; if (r <= mid) change(2 * x, l, r, z); else if (l > mid) change(2 * x + 1, l, r, z); else { change(2 * x, l, mid, z); change(2 * x + 1, mid + 1, r, z); } p[x].sum = (p[2 * x].sum + p[2 * x + 1].sum + p[2 * x].lazy * (p[2 * x].r - p[2 * x].l + 1) + p[2 * x + 1].lazy * (p[2 * x + 1].r - p[2 * x + 1].l + 1)); }long long xfind(int x, int l, int r) { if (p[x].lazy) update(x); if (p[x].l == l && p[x].r == r) { return (p[x].sum); } int mid = (p[x].l + p[x].r) >> 1; if (r <= mid) return (xfind(2 * x, l, r)); else if (l > mid) return (xfind(2 * x + 1, l, r)); else return (xfind(2 * x, l, mid) + xfind(2 * x + 1, mid + 1, r));}int main () { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); build(1, 1, n); for (int i = 1; i <= m; i++) { scanf("%d %d %d", &od, &x, &y); if (od == 1) { scanf("%d", &z); change(1, x, y, z); } else { printf("%lld\n", xfind(1, x, y)); } } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
单调队列:
传送门洛谷1886
改了一个世纪,,感觉单调队列有点虚,,错误点:
- q1和q2数组存储的应该是下标而非数据,处理过程中弄混
- 在前移队列尾指针时忘记控制尾指针小于头指针
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 1e6 + 500;const int inf = 0x7fffffff;int q1[maxn]; int q2[maxn]; int a[maxn];int q1h = 1, q1t = 1;int q2h = 1, q2t = 1;int n, k;int main () { freopen("window.in", "r", stdin); freopen("window.out", "w", stdout); scanf("%d %d", &n, &k); q2[0] = 0; q1[0] = 0; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); q1[1] = 1; for (int i = 2; i <= k; i++) { while (a[q1[q1t]] >= a[i] && q1t >= q1h) q1t--; q1t++; q1[q1t] = i; } printf("%d ", a[q1[1]]); for (int i = k + 1; i <= n; i++) { while (a[q1[q1t]] >= a[i] && q1t >= q1h) q1t--; q1t++; q1[q1t] = i; while (q1[q1h] <= i - k) q1h++; printf("%d ", a[q1[q1h]]); } q2[1] = 1; for (int i = 2; i <= k; i++) { while (a[q2[q2t]] <= a[i] && q2t >= q2h) q2t--; q2t++; q2[q2t] = i; } printf("\n%d ", a[q2[1]]); for (int i = k + 1; i <= n; i++) { while(a[q2[q2t]] <= a[i] && q2t >= q2h) q2t--; q2t++; q2[q2t] = i; while (q2[q2h] <= i - k) q2h++; printf("%d ", a[q2[q2h]]); } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
第二次做就熟悉了好多
传送门洛谷1440
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 2000000 + 5000;int q1[maxn];int q1h = 1, q1t = 1;int n, m;int a[maxn];int main () { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); printf("0\n"); q1[1] = 1; printf("%d\n", a[1]); for (int i = 2; i <= m; i++) { while (a[q1[q1t]] >= a[i] && q1t >= q1h) q1t--; q1t++; q1[q1t] = i; printf("%d\n", a[q1[1]]); } for (int i = m + 1; i < n; i++) { while (a[q1[q1t]] >= a[i] && q1t >= q1h) q1t--; q1t++; q1[q1t] = i; while (q1[q1h] <= i - m) q1h++; printf("%d\n", a[q1[q1h]]); } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
并查集:
传送门洛谷3367
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 10000 + 500;int father[maxn];int x, y, od;int n, m;int getfather(int x) { if (father[x] == x) return (x); return (father[x] = getfather(father[x]));}int main () { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) father[i] = i; for (int i = 1; i <= m; i++) { scanf("%d %d %d", &od, &x, &y); if (od == 1) { int tx = getfather(x); int ty = getfather(y); if (tx == ty) continue; father[tx] = ty; } else { int tx = getfather(x); int ty = getfather(y); if (tx == ty) printf("Y\n"); else printf("N\n"); } } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
平衡树:
传送门洛谷3369
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 100000 + 5000;int size[maxn], left[maxn], right[maxn], val[maxn];int n, m;int tot = 0;int t = 0;int oop, key;void right_rotate(int &t) { int k = left[t]; left[t] = right[k]; right[k] = t; size[k] = size[t]; size[t] = size[left[t]] + size[right[t]] + 1; t = k;}void left_rotate(int &t) { int k = right[t]; right[t] = left[k]; left[k] = t; size[k] = size[t]; size[t] = size[left[t]] + size[right[t]] + 1; t = k;}void maintain(int &t, bool flag) { if (flag) { if (size[right[right[t]]] > size[left[t]]) { left_rotate(t); } else if (size[left[right[t]]] > size[left[t]]) { right_rotate(right[t]); left_rotate(t); } else return; } else { if (size[left[left[t]]] > size[right[t]]) { right_rotate(t); } else if (size[right[left[t]]] > size[right[t]]) { left_rotate(left[t]); right_rotate(t); } else return; } maintain(left[t], 0); maintain(right[t], 1); maintain(t, 0); maintain(t, 1);}void insert1(int &t, int v) { if (t == 0) { tot++; t = tot; size[t] = 1; val[t] = v; left[t] = 0; right[t] = 0; } else { size[t]++; if (v < val[t]) { insert1(left[t], v); } else { insert1(right[t], v); } maintain(t, v >= val[t]); }}int delete2(int &t, int v) { int cur = 0; size[t]--; if (v == val[t] || (v > val[t] && right[t] == 0) || (v < val[t] && left[t] == 0)) { cur = val[t]; if (left[t] == 0 || right[t] == 0) { t = left[t] + right[t]; } else { val[t] = delete2(left[t], v + 1); } } else if (v < val[t]) cur = delete2(left[t], v); else cur = delete2(right[t], v); return (cur);}int rank3(int &t, int v) { if (t == 0) return (1); if (val[t] >= v) { return (rank3(left[t], v)); } else if (val[t] < v) { return (rank3(right[t], v) + size[left[t]] + 1); }}int find4(int &t, int v) { if (size[left[t]] + 1 == v) return (val[t]); else if (size[left[t]] + 1 < v) return (find4(right[t],v - size[left[t]] - 1)); else return (find4(left[t], v));}int pre5(int &t, int v) { if (t == 0) return (-1); if (v <= val[t]) { return (pre5(left[t], v)); } else { int cur = pre5(right[t], v); if (cur == -1) return (val[t]); return (cur); }}int succ6(int &t, int v) { if (t == 0) return (-1); if (v >= val[t]) { return (succ6(right[t], v)); } else { int cur = succ6(left[t], v); if (cur == -1) return (val[t]); return (cur); }}int main () { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d %d", &oop, &key); if (oop == 1) insert1(t, key); if (oop == 2) delete2(t, key); if (oop == 3) printf("%d\n", rank3(t,key)); if (oop == 4) printf("%d\n", find4(t, key)); if (oop == 5) printf("%d\n", pre5(t, key)); if (oop == 6) printf("%d\n", succ6(t, key)); } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
算法
最小生成树
传送门洛谷3366
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 6000;const int maxm = 210000;struct data { int from; int to; int val;};int father[maxn];data p[maxm];int n, m;int x, y, z;long long ans = 0;int cur;bool cmp(data aa, data bb) { return (aa.val < bb.val);}int getfather(int x) { if (father[x] == x) return (x); return (father[x] = getfather(father[x]));}int main () { scanf("%d %d", &n, &m); cur = n; for (int i = 1; i <= n; i++) father[i] = i; for (int i = 1; i <= m; i++) { scanf("%d %d %d", &p[i].from, &p[i].to, &p[i].val); } std :: sort(p + 1, p + m + 1, cmp); for (int i = 1; i <= m; i++) { int tx = getfather(p[i].from); int ty = getfather(p[i].to); if (tx != ty) { cur--; father[tx] = ty; ans += p[i].val; } } if (cur > 1) printf("orz"); else printf("%lld", ans); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
匈牙利算法:
传送门洛谷3386
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 2200;int line[maxn][maxn];int flag[maxn];int vis[maxn];int n, m, e;int ans = 0;int x, y;bool xfind(int x) { for (int j = 1; j <= m; j++) { if (line[x][j] && flag[j] == 0) { flag[j] = 1; if (vis[j] == 0 || xfind(vis[j])) { vis[j] = x; return 1; } } } return 0;}int main () { scanf("%d %d %d", &n, &m, &e); for (int i = 1; i <= e; i++) { scanf("%d %d", &x, &y); line[x][y] = 1; } for (int i = 1; i <= n; i++) { memset(flag, 0, sizeof(flag)); if (xfind(i)) ans++; } printf("%d", ans); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
SPFA:
传送门
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 15000;const int maxm = 500000 + 5000;const int inf = 0x7fffffff;int dis[maxn], que[maxn], vis[maxn];int last[maxn], pre[maxm], other[maxm], val[maxm];int tot = 1;int n, m, s;int x, y, z;void add(int x, int y, int z) { tot++; pre[tot] = last[x]; last[x] = tot; other[tot] = y; val[tot] = z;}void spfa(int s) { que[1] = s; for (int i = 1; i <= n; i++) dis[i] = inf; dis[s] = 0; int h = 0, t = 1; while (h != t) { h = (h + 1) % maxn; int cur = que[h]; vis[cur] = 0; for (int p = last[cur]; p; p = pre[p]) { int q = other[p]; if (dis[q] > dis[cur] + val[p]) { dis[q] = dis[cur] + val[p]; if (vis[q] == 0) { vis[q] = 1; t = (t + 1) % maxn; que[t] = q; } } } }}int main () { scanf("%d %d %d", &n, &m, &s); for (int i = 1; i <= m; i++) { scanf("%d %d %d", &x, &y, &z); add(x, y, z); } spfa(s); for (int i = 1; i <= n; i++) printf("%d ", dis[i]); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
堆+dijkstra:
传送门洛谷3371
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>const int maxn = 12000;const int maxm = 550000;const int inf = 0x7fffffff;int n, m;int s;int last[maxn], pre[maxm], other[maxm], len[maxm];int dis[maxn];bool vis[maxn];int tot = 0;int x, y, z;struct point{ int dis; int num; point(int num, int dis) : dis(dis), num(num) {}};bool operator < (point aa, point bb) { return (aa.dis > bb.dis);}std :: priority_queue <point> q1;void add(int x, int y, int z) { tot++; pre[tot] = last[x]; last[x] = tot; other[tot] = y; len[tot] = z;}void dijkstra(int s) { for (int i = 1; i <= n; i++) { dis[i] = inf; q1.push(point(i, dis[i])); } dis[s] = 0; q1.push(point(s, dis[s])); while (!q1.empty()) { point kkk = q1.top(); q1.pop(); if (kkk.dis == inf) return; if (vis[kkk.num]) continue; vis[kkk.num] = 1; for (int p = last[kkk.num]; p; p = pre[p]) { int q = other[p]; if (dis[q] > dis[kkk.num] + len[p]) { dis[q] = dis[kkk.num] + len[p]; q1.push(point(q, dis[q])); } } }}int main () { scanf("%d %d %d", &n, &m, &s); for (int i = 1; i <= m; i++) { scanf("%d %d %d", &x, &y, &z); add(x, y, z); } dijkstra(s); for (int i = 1; i <= n; i++) printf("%d ", dis[i]); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
KMP:
传送门洛谷3375
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 1100000;const int maxm = 1100;int next[maxm];char s1[maxn];char s2[maxm];int main () { scanf("%s %s", s1, s2); int len1 = strlen(s1); int len2 = strlen(s2); for (int i = 1, p = 0; i < len2; i++) { while (s2[i] != s2[p] && p > 0) p = next[p-1]; if (s2[i] == s2[p]) p++; next[i] = p; } for (int i = 0, p = 0; i < len1; i++) { while (s1[i] != s2[p] && p > 0) p = next[p-1]; if (s1[i] == s2[p]) p++; if (p == len2) { printf("%d\n", i - len2 + 2); p = next[p-1]; } } for (int i = 0; i < len2; i++) printf("%d ", next[i]); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
倍增LCA:
传送门洛谷3379
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 550000;int n, m, s;int last[maxn], pre[maxn * 2], other[maxn * 2];int jump[maxn][30];int dis[maxn];int tot = 0;int x, y;void add(int x, int y) { tot++; pre[tot] = last[x]; last[x] = tot; other[tot] = y;}void dfs(int x, int come) { jump[x][0] = come; dis[x] = dis[come] + 1; for (int p = last[x]; p; p = pre[p]) { int q = other[p]; if (q == come) continue; dfs(q, x); }}int lca(int x, int y) { if (dis[x] < dis[y]) std :: swap(x, y); if (dis[x] != dis[y]) { for (int j = 25; j >= 0; j--) if (dis[jump[x][j]] > dis[y]) x = jump[x][j]; x = jump[x][0]; } if (x == y) return (x); for (int j = 25; j >= 0; j--) { if (jump[x][j] != jump[y][j]) { x = jump[x][j]; y = jump[y][j]; } } return jump[x][0];}int main () { scanf("%d %d %d", &n, &m, &s); for (int i = 1; i < n; i++) { scanf("%d %d", &x, &y); add(x, y); add(y, x); } dfs(s, 0); for (int i = 1; i <= 25; i++) for (int j = 1; j <= n; j++) jump[j][i] = jump[jump[j][i-1]][i-1]; for (int i = 1; i <= m; i++) { scanf("%d %d", &x, &y); printf("%d\n", lca(x, y)); } return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
Tarjan求环:
传送门洛谷2661
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 300000;int next[maxn];int dfn[maxn], low[maxn], size[maxn], belong[maxn];bool vis[maxn];int sta[maxn];int statot = 0;int cur = 0;int tim = 0;int n;int ans = 0x7fffffff;void tarjan(int x) { tim++; dfn[x] = low[x] = tim; statot++; vis[x] = 1; sta[statot] = x; int q = next[x]; if (!dfn[q]) { tarjan(q); low[x] = std :: min(low[x], low[q]); } else if (vis[q]) { low[x] = std :: min(dfn[q], low[x]); } if (dfn[x] == low[x]) { cur++; while (sta[statot] != x) { belong[sta[statot]] = cur; vis[sta[statot]] = 0; size[cur]++; statot--; } belong[x] = cur; statot--; size[cur]++; }}int main () { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &next[i]); for (int i = 1; i <= n; i++) { if (!dfn[i]) tarjan(i); } for (int i = 1; i <= cur; i++) { if (size[i] > 1) ans = std :: min(ans, size[i]); } printf("%d", ans); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
归并排序:
传送门洛谷1177
#include <cstdio>#include <cstring>#include <algorithm>const int maxn = 100000 + 5000;int tmp[maxn];int a[maxn];int n;void merg(int *a, int l, int mid, int r) { int cur = 1; int k1 = l; int k2 = mid + 1; while (k1 <= mid && k2 <= r) { if (a[k1] < a[k2]) { tmp[cur] = a[k1]; cur++; k1++; } else { tmp[cur] = a[k2]; cur++; k2++; } } while (k1 <= mid) { tmp[cur] = a[k1]; cur++; k1++; } while (k2 <= mid) { tmp[cur] = a[k2]; k2++; cur++; } memcpy(a + l, tmp + 1, sizeof(int) * (cur - 1));}void m_sort(int *a, int l, int r) { if (l < r) { int mid = (l + r) >> 1; m_sort(a, l, mid); m_sort(a, mid + 1, r); merg(a, l, mid, r); }}int main () { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); m_sort(a, 1, n); for (int i = 1; i <= n; i++) printf("%d ", a[i]); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
网络流(dinic):
传送门洛谷3376
#include <cstdio>#include <algorithm>#include <cstring>using std :: min;const int maxm = 200000 + 1000;const int maxn = 10000 + 500;int last[maxn], pre[maxm], other[maxm], cap[maxm];int tot = 1;int s, t, n, m;int x, y, z;int dis[maxn], vis[maxn];int que[maxn];void add(int x, int y, int z) { tot++; pre[tot] = last[x]; last[x] = tot; other[tot] = y; cap[tot] = z;}bool bfs(void) { memset(dis, 0, sizeof(dis)); memset(vis, 0, sizeof(vis)); int queh = 0, quet = 1; que[1] = s; vis[s] = dis[s] = 1; while (queh < quet) { queh++; int cur = que[queh]; for (int p = last[cur]; p; p = pre[p]) { int q = other[p]; if (cap[p] && !vis[q]) { vis[q] = 1; dis[q] = dis[cur] + 1; quet++; que[quet] = q; } } } return (dis[t] > 0);}int dinic(int x, int flow) { if (x == t) return (flow); int ret = 0; for (int p = last[x]; p; p = pre[p]) { int q = other[p]; if (cap[p] && flow && dis[q] == dis[x] + 1) { int push = dinic(q, min(cap[p], flow)); if (!push) dis[q] = 0; flow -= push; ret += push; cap[p] -= push; cap[p ^ 1] += push; } } return (ret);}int main () { scanf("%d %d %d %d", &n, &m, &s, &t); for (int i = 1; i <= m; i++) { scanf("%d %d %d", &x, &y, &z); add(x, y, z); add(y, x, 0); } int ans = 0; while (bfs()) { ans += dinic(s, 0x7fffffff); } printf("%d\n", ans); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
字符串hash:
传送门洛谷3370
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int mod = 1e7 + 19;const int base = 31;const int step = 72;int hasht[mod];char s[1600];int n;int ans = 0;char hs[10005][1600];int tot = 0;int main () { ios_base :: sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> s; long long cur = 0; int len = strlen(s); for (int i = 0; i < len; i++) { cur = (cur * base + (int)s[i]) % mod; } bool ft = 0; while (hasht[cur] != 0) { if (strcmp(hs[hasht[cur]], s) == 0) { ft = 1; break; } cur = (cur + step) % mod; } if (ft) continue; tot++; hasht[cur] = tot; ans++; strcpy(hs[tot], s); } cout << ans << endl; return 0;}