模板合集

未分类

轻重链剖分

// time : 20210103
// test on https://www.luogu.com.cn/problem/P3384

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 100001

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x;
}

int n, m, r, p, a[M], dfn[M], pre[M], size[M];

namespace Seg {
    #define lson now << 1
    #define rson now << 1 | 1
    struct Node {
        int l, r, w, lazy;
    }tree[M << 2];
    void build(int l, int r, int now) {
        tree[now].l = l, tree[now].r = r;
        if (tree[now].l == tree[now].r) {
            tree[now].w = a[pre[l]]; return;
        }
        int mid = (tree[now].l + tree[now].r) >> 1;
        build(l, mid, lson), build(mid + 1, r, rson);
        tree[now].w = (tree[lson].w + tree[rson].w) % p;
    }
    void pushdown(int now) {
        if (tree[now].l == tree[now].r) return;
        tree[lson].lazy = (tree[lson].lazy + tree[now].lazy) % p;
        tree[rson].lazy = (tree[rson].lazy + tree[now].lazy) % p;
        tree[lson].w = (tree[lson].w + 1ll * (tree[lson].r - tree[lson].l + 1) * tree[now].lazy % p) % p;
        tree[rson].w = (tree[rson].w + 1ll * (tree[rson].r - tree[rson].l + 1) * tree[now].lazy % p) % p;
        tree[now].lazy = 0; return;
    }
    void update(int x, int y, int k, int now) {
        if (tree[now].l >= x && tree[now].r <= y) {
            tree[now].w = (tree[now].w + 1ll * (tree[now].r - tree[now].l + 1) * k % p) % p;
            tree[now].lazy = (tree[now].lazy + k) % p; return;
        }
        if (tree[now].lazy) pushdown(now);
        int mid = (tree[now].l + tree[now].r) >> 1;
        if (x <= mid) update(x, y, k, lson);
        if (y > mid) update(x, y, k, rson);
        tree[now].w = (tree[lson].w + tree[rson].w) % p;
    }
    int query(int x, int y, int now) {
        if (tree[now].l >= x && tree[now].r <= y) return tree[now].w;
        if (tree[now].lazy) pushdown(now);
        int mid = (tree[now].l + tree[now].r) >> 1, ans = 0;
        if (x <= mid) ans = (ans + query(x, y, lson)) % p;
        if (y > mid) ans = (ans + query(x, y, rson)) % p;
        return ans;
    }
}

namespace Cut {
    int pthn, dep[M], head[M];
    int cnt, fa[M], son[M], top[M];
    struct Edge {
        int nxt, to;
    }pth[M << 1];
    void add(int frm, int to) {
        pth[++pthn].to = to, pth[pthn].nxt = head[frm];
        head[frm] = pthn;
    }
    void dfs1(int u, int father) {
        fa[u] = father, dep[u] = dep[father] + 1, size[u] = 1;
        for (int i = head[u]; i; i = pth[i].nxt) {
            int v = pth[i].to;
            if (v != father) {
                dfs1(v, u), size[u] += size[v];
                if (size[v] > size[son[u]]) son[u] = v;
            }
        }
    }
    void dfs2(int u, int tp) {
        dfn[u] = ++cnt, pre[cnt] = u, top[u] = tp;
        if (son[u]) dfs2(son[u], tp);
        for (int i = head[u]; i; i = pth[i].nxt) {
            int v = pth[i].to;
            if (v != fa[u] && v != son[u]) dfs2(v, v);
        }
    }
    void change(int x, int y, int k) {
        while (top[x] != top[y]) {
            if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
            Seg::update(dfn[top[x]], dfn[x], k, 1);
            x = fa[top[x]];
        }
        if (dfn[x] > dfn[y]) std::swap(x, y);
        Seg::update(dfn[x], dfn[y], k, 1); 
    }
    int ask(int x, int y) {
        int ans = 0;
        while (top[x] != top[y]) {
            if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
            ans = (ans + Seg::query(dfn[top[x]], dfn[x], 1)) % p;
            x = fa[top[x]];
        }
        if (dfn[x] > dfn[y]) std::swap(x, y);
        ans = (ans + Seg::query(dfn[x], dfn[y], 1)) % p;
        return ans;
    }
}

int main() {
    read(n), read(m), read(r), read(p);
    for (int i = 1; i <= n; ++i) read(a[i]);
    for (int i = 1, u, v; i < n; ++i) {
        read(u), read(v);
        Cut::add(u, v), Cut::add(v, u);
    }
    Cut::dfs1(r, 0), Cut::dfs2(r, r), Seg::build(1, n, 1);
    for (int i = 1, opt, x, y, k; i <= m; ++i) {
        read(opt), read(x);
        if (opt == 1) { read(y), read(k), Cut::change(x, y, k); }
        if (opt == 2) { read(y), printf("%d\n", Cut::ask(x, y)); }
        if (opt == 3) { read(y), Seg::update(dfn[x], dfn[x] + size[x] - 1, y, 1); }
        if (opt == 4) { printf("%d\n", Seg::query(dfn[x], dfn[x] + size[x] - 1, 1)); }
    }
    return 0;
}

线段树

// time : 20210103
// test on https://www.luogu.com.cn/problem/P3373

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 100001
#define lson now << 1
#define rson now << 1 | 1

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x;
}

int n, m, p;
struct Node {
    int l, r, w, add, mul;
}tree[M << 2];

void build(int l, int r, int now) {
    tree[now].l = l, tree[now].r = r;
    tree[now].add = 0, tree[now].mul = 1;
    if (tree[now].l == tree[now].r) {
        read(tree[now].w); return;
    }
    int mid = (tree[now].l + tree[now].r) >> 1;
    build(l, mid, lson), build(mid + 1, r, rson);
    tree[now].w = (tree[lson].w + tree[rson].w) % p;
}

void pushdown(int now) {
    if (tree[now].l == tree[now].r) return;
    tree[lson].mul = 1ll * tree[lson].mul * tree[now].mul % p;
    tree[rson].mul = 1ll * tree[rson].mul * tree[now].mul % p;
    tree[lson].add = (1ll * tree[lson].add * tree[now].mul % p + tree[now].add) % p;
    tree[rson].add = (1ll * tree[rson].add * tree[now].mul % p + tree[now].add) % p;
    tree[lson].w = (1ll * tree[lson].w * tree[now].mul % p + 1ll * (tree[lson].r - tree[lson].l + 1) * tree[now].add % p) % p;
    tree[rson].w = (1ll * tree[rson].w * tree[now].mul % p + 1ll * (tree[rson].r - tree[rson].l + 1) * tree[now].add % p) % p;
    tree[now].mul = 1, tree[now].add = 0;
}

void update1(int x, int y, int k, int now) {
    if (tree[now].l >= x && tree[now].r <= y) {
        tree[now].w = 1ll * tree[now].w * k % p;
        tree[now].mul = 1ll * tree[now].mul * k % p;
        tree[now].add = 1ll * tree[now].add * k % p;
        return;
    }
    if (tree[now].mul != 1 || tree[now].add) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1;
    if (x <= mid) update1(x, y, k, lson);
    if (y > mid) update1(x, y, k, rson);
    tree[now].w = (tree[lson].w + tree[rson].w) % p;
}

void update2(int x, int y, int k, int now) {
    if (tree[now].l >= x && tree[now].r <= y) {
        tree[now].w = (tree[now].w + 1ll * (tree[now].r - tree[now].l + 1) * k % p) % p;
        tree[now].add = (tree[now].add + k) % p; return;
    }
    if (tree[now].mul != 1 || tree[now].add) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1;
    if (x <= mid) update2(x, y, k, lson);
    if (y > mid) update2(x, y, k, rson);
    tree[now].w = (tree[lson].w + tree[rson].w) % p;
}

int query(int x, int y, int now) {
    if (tree[now].l >= x && tree[now].r <= y) return tree[now].w;
    if (tree[now].mul != 1 || tree[now].add) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1, ans = 0;
    if (x <= mid) ans = (ans + query(x, y, lson)) % p;
    if (y > mid) ans = (ans + query(x, y, rson)) % p;
    return ans;
}

int main() {
    read(n), read(m), read(p);
    build(1, n, 1);
    for (int i = 1, opt, x, y, k; i <= m; ++i) {
        read(opt), read(x), read(y);
        if (opt == 1) { read(k), update1(x, y, k, 1); }
        if (opt == 2) { read(k), update2(x, y, k, 1); }
        if (opt == 3) printf("%d\n", query(x, y, 1));
    }
    return 0;
}

树状数组

// time : 20210103
// test on https://www.luogu.com.cn/problem/P3374
// test on https://www.luogu.com.cn/problem/P3368

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 500001
#define lowbit(x) x & (-x)

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x;
}

int n, m;
struct Bit {
    int c[M];
    void add(int x, int k) {
        while (x <= n) { c[x] += k, x += lowbit(x); }
    }
    int ask(int x, int ans = 0) {
        while (x > 0) { ans += c[x], x -= lowbit(x); }
        return ans;
    }
}b;

int main() {
    read(n), read(m);
    
    //bit1
    for (int i = 1, x; i <= n; ++i) {
        read(x), b.add(i, x);
    }
    for (int i = 1, opt, x, y; i <= m; ++i) {
        read(opt), read(x), read(y);
        if (opt == 1) b.add(x, y);
        else printf("%d\n", b.ask(y) - b.ask(x - 1));
    }
    
    //bit2
    for (int i = 1, last = 0, x; i <= n; ++i, last = x) {
        read(x), b.add(i, x - last);
    }
    for (int i = 1, opt, x, y, k; i <= m; ++i) {
        read(opt), read(x);
        if (opt == 1) {
            read(y), read(k);
            b.add(x, k), b.add(y + 1, -k);
        }
        else printf("%d\n", b.ask(x));
    }
    
    return 0;
}

回滚莫队(不删除莫队)

// time : 20210103
// test on https://www.luogu.com.cn/problem/P5906

#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 200001

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x; 
}

int n, m, a[M], fir[M], las[M];
int sqrn, num[M], ans[M], fir_[M];
struct query {
    int x, y, id;
    friend bool operator < (query q1, query q2) {
        if (num[q1.x] == num[q2.x]) return q1.y < q2.y;
        else return num[q1.x] < num[q2.x];
    }
}q[M];
struct lsh {
    int w, id;
    friend bool operator < (lsh l1, lsh l2) {
        return l1.w < l2.w;
    }
}b[M];

int main() {
    read(n), sqrn = sqrt(n);
    for (int i = 1; i <= n; ++i) {
        read(a[i]);
        b[i].id = i, b[i].w = a[i];
        num[i] = (i - 1) / sqrn + 1;
    }
    std::sort(b + 1, b + n + 1);
    for (int i = 1, now = 0; i <= n; ++i) {
        if (b[i].w != b[i - 1].w) ++now;
        a[b[i].id] = now;
    }
    read(m);
    for (int i = 1; i <= m; ++i) {
        read(q[i].x), read(q[i].y);
        q[i].id = i;
    }
    std::sort(q + 1, q + m + 1);
    int l = 1, r = 0, now = 0, lasb = 0;
    for (int i = 1; i <= m; ++i) {
        if (num[q[i].x] == num[q[i].y]) {
            int temp = 0;
            for (int j = q[i].x; j <= q[i].y; ++j) {
                if (!fir_[a[j]]) fir_[a[j]] = j;
                else temp = max(temp, j - fir_[a[j]]);
            }
            for (int j = q[i].x; j <= q[i].y; ++j) fir_[a[j]] = 0;
            ans[q[i].id] = temp; continue;
        }
        if (lasb != num[q[i].x]) {
            int stop = min(num[q[i].x] * sqrn, n );
            memset(fir, 0, sizeof fir), memset(las, 0, sizeof las);
            l = stop + 1, r = stop, now = 0, lasb = num[q[i].x];
        }
        while (r < q[i].y) {
            ++r;
            if (!fir[a[r]]) fir[a[r]] = las[a[r]] = r;
            else {
                las[a[r]] = r;
                now = max(now, r - fir[a[r]]);
            }
        }
        int l_ = l, temp = now;
        while (l_ > q[i].x) {
            --l_;
            if (!las[a[l_]] && !fir[a[l_]]) las[a[l_]] = l_;
            else temp = max(temp, las[a[l_]] - l_);
        }
        ans[q[i].id] = temp;
        while (l_ < l) {
            if (!fir[a[l_]]) las[a[l_]] = 0;
            ++l_;
        }
    }
    for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
    return 0;
}

单调栈

// time : 20210103
// test on https://www.luogu.com.cn/problem/P5788

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <stack>
#define M 3000001

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x;
}

std::stack<int> s;
int n, a[M], ans[M];

int main() {
    read(n);
    for (int i = 1; i <= n; ++i) read(a[i]);
    for (int i = 1; i <= n; ++i) {
        while (!s.empty() && a[s.top()] < a[i]) {
            ans[s.top()] = i; s.pop();
        }
        s.push(i);
    }
    for (int i = 1; i <= n; ++i) printf("%d ", ans[i]);
    return 0;
}

单调队列

// time : 20210103
// test on https://www.luogu.com.cn/problem/P1886

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#define M 1000001

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x;
}

std::deque<int> q1, q2;
int n, k, a[M], min[M], max[M];

int main() {
    read(n), read(k);
    for (int i = 1; i <= n; ++i) read(a[i]);
    for (int i = 1; i <= n; ++i) {
        while (!q1.empty() && q1.front() < i - k + 1) q1.pop_front();
        while (!q2.empty() && q2.front() < i - k + 1) q2.pop_front();
        while (!q1.empty() && a[q1.back()] >= a[i]) q1.pop_back();
        while (!q2.empty() && a[q2.back()] <= a[i]) q2.pop_back();
        q1.push_back(i), q2.push_back(i);
        min[i] = a[q1.front()], max[i] = a[q2.front()];
    }
    for (int i = k; i <= n; ++i) printf("%d ", min[i]);
    puts("");
    for (int i = k; i <= n; ++i) printf("%d ", max[i]);
    return 0;
}

倍增求LCA

// time : 20210110
// test on https://www.luogu.com.cn/problem/P3379

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 500001

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x;
}

int n, m, s, pthn, head[M];
int lg[M], dep[M], fa[M][21];
struct Edge {
    int nxt, to;
}pth[M << 1];

void add(int frm, int to) {
    pth[++pthn].to = to, pth[pthn].nxt = head[frm];
    head[frm] = pthn;
}

void dfs(int u, int father) {
    fa[u][0] = father, dep[u] = dep[father] + 1;
    for (int i = head[u]; i; i = pth[i].nxt) {
        int x = pth[i].to;
        if (x != father) dfs(x, u);
    }
}

int lca(int x, int y) {
    if (dep[x] < dep[y]) std::swap(x, y);
    while (dep[x] > dep[y]) {
        x = fa[x][lg[dep[x] - dep[y]] - 1];
    }
    if (x == y) return x;
    for (int k = lg[dep[x]] - 1; k >= 0; --k) {
        if (fa[x][k] != fa[y][k]) {
            x = fa[x][k];
            y = fa[y][k];
        }
    }
    return fa[x][0];
}

int main() {
    read(n), read(m), read(s);
    for (int i = 1, u, v; i < n; ++i) {
        read(u), read(v);
        add(u, v), add(v, u);
    }
    for (int i = 1; i <= n; ++i) {
        lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i);
    }
    dfs(s, 0);
    for (int j = 1; (1 << j) <= n; ++j) {
        for (int i = 1; i <= n; ++i) {
            fa[i][j] = fa[fa[i][j - 1]][j - 1];
        }
    }
    for (int i = 1, x, y; i <= m; ++i) {
        read(x), read(y);
        printf("%d\n", lca(x, y));
    }
    return 0;
}

图论

最小生成树(Kruskal)

// date: 20210409
// test on: https://www.luogu.com.cn/problem/P3366

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 200001

inline void read(int &T) {
  int x = 0; bool f = 0; char c = getchar();
  while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
  while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
  T = f ? -x : x;
}

int n, m, ub, ans, fa[M];
struct Edge {
  int u, v, w;
  friend bool operator < (Edge e1, Edge e2) {
    return e1.w < e2.w;
  }
}e[M];

int find(int x) { return x == fa[x] ? fa[x] : fa[x] = find(fa[x]); }

int main() {
  read(n), read(m), ub = n;
  for (int i = 1; i <= n; ++i) fa[i] = i;
  for (int i = 1; i <= m; ++i) {
    read(e[i].u), read(e[i].v), read(e[i].w);
  }
  std::sort(e + 1, e + m + 1);
  for (int i = 1; i <= m; ++i) {
    int rx = find(e[i].u), ry = find(e[i].v);
    if (rx != ry) fa[rx] = ry, --ub, ans += e[i].w;
    if (ub == 1) break;
  }
  if (ub == 1) std::cout << ans << '\n';
  else std::cout << "orz\n";
  return 0;
}

最小生成树(Prim)

// date: 20210409
// test on: https://www.luogu.com.cn/problem/P3366

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 200001

inline void read(int &T) {
  int x = 0; bool f = 0; char c = getchar();
  while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
  while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
  T = f ? -x : x;
}

bool vis[M];
int n, m, pthn, dis[M], head[M];
struct Edge {
  int nxt, to, w;
}pth[M << 1];

void add(int frm, int to, int w) {
  pth[++pthn].to = to, pth[pthn].nxt = head[frm];
  pth[pthn].w = w, head[frm] = pthn;
}

void Prim() {
  memset(dis, 0x3f, sizeof dis);
  dis[1] = 0;
  for (int i = 1; i <= n; ++i) {
    int k = 0;
    for (int j = 1; j <= n; ++j) {
      if (!vis[j] && dis[k] > dis[j]) k =j;
    }
    vis[k] = true;
    for (int j = head[k]; j; j = pth[j].nxt) {
      int v = pth[j].to;
      if (!vis[v] && dis[v] > pth[j].w) dis[v] = pth[j].w;
    }
  }
}

int main() {
  read(n), read(m);
  for (int i = 1, x, y, z; i <= m; ++i) {
    read(x), read(y), read(z);
    add(x, y, z), add(y, x, z);
  }
  Prim(); int ans = 0;
  for (int i = 1; i <= n; ++i) {
    if (dis[i] == 0x3f3f3f3f) { puts("orz"); return 0; }
    ans += dis[i];
  }
  std::cout << ans << '\n';
  return 0;
}

缩点(tarjan)

// time : 20210103
// test on https://www.luogu.com.cn/problem/P3387

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#define M 100001

int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }

inline void read(int &T) {
    int x = 0; bool f = 0; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
    while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    T = f ? -x : x;
}

bool vis[M];
std::queue<int> q;
int n, m, ans, a[M], x[M], y[M], f[M], pthn, head[M];
int c, t, sc, b[M], s[M], dfn[M], low[M], num[M], ideg[M];
struct Edge {
    int nxt, to;
}pth[M];

void add(int frm, int to) {
    pth[++pthn].to = to, pth[pthn].nxt = head[frm];
    head[frm] = pthn;
}

void format() {
    memset(head, 0, sizeof head);
    for (int i = 1; i <= pthn; ++i) {
        pth[i].nxt = pth[i].to = 0;
    }
    pthn = 0;
}

void tarjan(int u) {
    low[u] = dfn[u] = ++c;
    vis[u] = true, s[++sc] = u;
    for (int i = head[u]; i; i = pth[i].nxt) {
        int v = pth[i].to;
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if (vis[v]) low[u] = min(low[u], dfn[v]);
    }
    if (low[u] == dfn[u]) {
        int now = s[sc--]; num[now] = ++t;
        b[t] += a[now], vis[now] = false;
        while (now != u) {
            now = s[sc--], num[now] = t;
            b[t] += a[now], vis[now] = false;
        }
    }
}

int main() {
    read(n), read(m);
    for (int i = 1; i <= n; ++i) read(a[i]);
    for (int i = 1; i <= m; ++i) {
        read(x[i]), read(y[i]);
        add(x[i], y[i]);
    }
    for (int i = 1; i <= n; ++i) {
        if (!dfn[i]) tarjan(i);
    }
    format();
    for (int i = 1; i <= m; ++i) {
        if (num[x[i]] != num[y[i]]) {
            add(num[x[i]], num[y[i]]);
            ++ideg[num[y[i]]];
        }
    }
    for (int i = 1; i <= t; ++i) {
        if (!ideg[i]) q.push(i), f[i] = b[i];
    }
    while (!q.empty()) {
        int u = q.front(); q.pop();
        ans = max(ans, f[u]);
        for (int i = head[u]; i; i = pth[i].nxt) {
            int v = pth[i].to; --ideg[v];
            f[v] = max(f[v], f[u] + b[v]);
            if (!ideg[v]) q.push(v);
        }
    }
    std::cout << ans << '\n';
    return 0;
}

字符串相关

manacher

// date: 20210203
// test on: https://www.luogu.com.cn/problem/P3805

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

#define N 11000001
inline int min(int a, int b) { return a < b ? a : b; }
inline int max(int a, int b) { return a > b ? a : b; }
inline void read(int &T) {
  int x = 0; bool f = 0; char c = getchar();
  while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
  while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
  T = f ? -x : x;
}

int l[2 * N + 1];
char s0[N], s[2 * N + 1];

int main() {
  scanf("%s", s0);
  int len = strlen(s0); s[0] = '~';
  for (int i = 1; i <= 2 * len + 1; ++i) {
    if (i & 1) s[i] = '|';
    else s[i] = s0[i / 2 - 1];
  }
  int r = 0, p = 0, ans = 0;
  for (int i = 1; i <= 2 * len + 1; ++i) {
    if (i <= r) l[i] = min(l[2 * p - i], r - i + 1);
    while (s[i - l[i]] == s[i + l[i]]) ++ l[i];
    if (i + l[i] - 1 > r) r = i + l[i] - 1, p = i;
    if (l[i] > ans) ans = l[i];
  }
  std::cout << ans - 1 << '\n';
  return 0;
}

Trie

// time : 20210109
// test on https://www.luogu.com.cn/problem/P2580

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 500001

int n, m;
std::string s;
struct Trie {
    int ender[M];
    int cnt, node[M][27];
    void clear() {
        cnt = 0;
        memset(node, 0, sizeof node);
        memset(ender, 0, sizeof ender);
    }
    void ins() {
        int len = s.length(), now = 0;
        for (int i = 0; i < len; ++i) {
            if (!node[now][s[i] - 'a']) node[now][s[i] - 'a'] = ++cnt;
            now = node[now][s[i] - 'a'];
        }
        ender[now] = true;
    }
    void find() {
        int len = s.length(), now = 0;
        for (int i = 0 ; i < len; ++i) {
            if (node[now][s[i] - 'a']) now = node[now][s[i] - 'a'];
            else { puts("WRONG"); return; }
        }
        ++ender[now];
        if (ender[now] > 2) puts("REPEAT");
        else puts("OK");
    }
}t;

int main() {
    scanf("%d", &n); t.clear();
    for (int i = 1; i <= n; ++i) { std::cin >> s; t.ins(); }
    scanf("%d", &m);
    for (int i = 1; i <= m; ++i) { std::cin >> s; t.find(); }
    return 0;
}

数论

快速幂

// time : 20211020
// test on https://www.luogu.com.cn/problem/P1226
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

typedef long long ll;
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
inline void read(int &T) {
  int x = 0; bool f = 0; char c = getchar();
  while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
  while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
  T = f ? -x : x;
}

int a, b, p;

int qpow() {
  int ans = 1, base = a;
  while (b) {
    if (b & 1) ans = 1ll * ans * base % p;
    base = 1ll * base * base % p;
    b >>= 1;
  }
  return ans % p;
}

int main() {
  read(a), read(b), read(p);
  printf("%d^%d mod %d=", a, b, p);
  printf("%d\n", qpow());
  return 0;
}

快速乘(龟速乘)

// time : 20211020
// test on N/A
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 100000001

typedef long long ll;
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
inline void read(ll &T) {
  ll x = 0; bool f = 0; char c = getchar();
  while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
  while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
  T = f ? -x : x;
}

ll a, b, p;

ll qmul(int x, int y) {
  ll ans = 0, base = x;
  while (y) {
    if (y & 1) ans = (ans + base) % p;
    base = (base + base) % p;
    y >>= 1;
  }
  return ans % p;
}

int main() {
  read(a), read(b), read(p);
  std::cout << qmul(a, b) << '\n';
  return 0;
}

欧拉筛筛素数

// time : 20211020
// test on https://www.luogu.com.cn/problem/P3383
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 100000001

typedef long long ll;
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
inline void read(int &T) {
  int x = 0; bool f = 0; char c = getchar();
  while (c < '0' || c > '9') { if (c == '-') f = !f; c = getchar(); }
  while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
  T = f ? -x : x;
}

bool okay[M];
int n, q, c, prm[M];

void get_prm(int x) {
  for (int i = 2; i <= x; ++i) {
    if (!okay[i]) prm[++c] = i;
    for (int j = 1; j <= c; ++j) {
      if (i * prm[j] > x) break;
      okay[i * prm[j]] = true;
      if(i % prm[j] == 0) break;
    }
  }
}

int main() {
  read(n), read(q), get_prm(n);
  for (int i = 1, k; i <= q; ++i) {
    read(k);
    printf("%d\n", prm[k]);
  }
  return 0;
}
posted @ 2021-01-03 11:16  yu__xuan  阅读(127)  评论(0编辑  收藏  举报