oi模板库

来源:互联网 发布:linux jdk6安装教程 编辑:程序博客网 时间:2024/06/09 16:03

目录(?)[+]

    • 数学有关的东西
      • 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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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));    // printf("%d", n);    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();    // aa.print();    // bb.print();    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];       //  minint q2[maxn];       //  maxint 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;}
原创粉丝点击