CSP 2019 模板整合

qwq以下都为9.24后写的模板

快读

inline int read() {
    int x = 0, k = 1; char c = getchar();
    for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    return k ? x : -x;
}

快速幂

inline int ksm(int a, int b) {
    int ans = 1;
    for (; b; b >>= 1, a = 1LL * a * a % Mo)
        if (b & 1) ans = 1LL * ans * a % Mo;
    return ans;
}

扩欧

void exgcd(int a, int b) {
    if (b == 0) {
        x = 1, y = 0;
        return;
    }
    exgcd(b, a % b);
    int k = x;
    x = y, y = k - a / b * y;
}

后缀自动机(PAM) (9.24)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
char s[N];
int Len;
struct PAM{
    int last, cnt, len[N], fail[N], num[N], k, p, ch[N][26], p1, c[N];
    //char s[N];
    void init(char *s) {
        last = 0, cnt = 1, len[0] = 0, len[1] = -1, fail[0] = 1, fail[1] = 0, s[0] = 26;
    }
    void insert() {
        for (int i = 1; i <= Len; i++) {
            s[i] = (s[i] - 97 + k) % 26 + 97;
            c[i] = s[i] - 'a';
            p = last;
            while (s[i - len[p] - 1] != s[i])
                p = fail[p];
            if (!ch[p][s[i]]) {
                len[++cnt] = len[p] + 2, p1 = fail[p];
                while (s[i - len[p1] - 1] != s[i])
                    p1 = fail[p1];
                fail[cnt] = ch[p1][s[i]];
                num[cnt] = num[fail[cnt]] + 1;
                ch[p][s[i]] = cnt;
            }
            last = ch[p][s[i]];
            printf("%d%c", num[last], (i == Len) ? '\n' : ' ');
            k = num[last];
            }
    }
} s1;
int main() {
    scanf("%s", s + 1);
    Len = strlen(s + 1);
    s1.init(s);
    s1.insert();
    return 0;
}

AC自动机 (9.25)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10, M = 160;
int n;
char s[M][N];
int trie[N][26], tot, endword[N], fail[N];
struct Node {
    int num, pos;
} Ans[N];
inline void Init(int x) {
    memset(trie[x], 0, sizeof(trie[x]));
    fail[x] = endword[x] = 0;
}
inline void Build_Trie(int gg) {
    int root = 0, len = strlen(s[gg] + 1);
    for (int j = 1; j <= len; j++) {
        if (!trie[root][s[gg][j] - 'a'])
            trie[root][s[gg][j] - 'a'] = ++tot, Init(tot);
        root = trie[root][s[gg][j] - 'a'];
    }
    endword[root] = gg;
}
inline void Get_Fail() {
    queue <int> q;
    for (int i = 0; i < 26; i++)
        if (trie[0][i]) {
            q.push(trie[0][i]);
            fail[trie[0][i]] = 0;
        }
    while (!q.empty()) {
        int now = q.front();
        q.pop();
        for (int i = 0; i < 26; i++)
            if (trie[now][i]) {
                fail[trie[now][i]] = trie[fail[now]][i];
                q.push(trie[now][i]);
            }
            else {
                trie[now][i] = trie[fail[now]][i];
            }
    }
}
inline int query() {
    int len = strlen(s[n + 1] + 1), ans = 0, now = 0;
    for (int i = 1; i <= len; i++) {
        now = trie[now][s[n + 1][i] - 'a'];
        for (int j = now; j; j = fail[j])
            Ans[endword[j]].num++;
    }
    return ans;
}
inline bool cmp(Node x, Node y) {
    return x.num > y.num || (x.num == y.num && x.pos < y.pos);
}
int main() {
    scanf("%d", &n);
    while (n != 0) {
        tot = 0;
        Init(0);
        for (int i = 1; i <= n; i++) {
            scanf("%s", s[i] + 1);
            Ans[i].num = 0, Ans[i].pos = i;
            Build_Trie(i);
        }
        fail[0] = 0;
        Get_Fail();
        scanf("%s", s[n + 1] + 1);
        query();
        std::sort(Ans + 1, Ans + 1 + n, cmp);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
        printf("%d\n%s\n", Ans[1].num, s[Ans[1].pos] + 1);
        for (int i = 2; i <= n; i++)
            if (Ans[1].num == Ans[i].num)
                printf("%s\n", s[Ans[i].pos] + 1);
            else 
                break;
        scanf("%d", &n);
    }
    return 0;
}

可持久化线段树(主席树) (9.25)

题目

(静态区间第k小)

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int l[N << 5], r[N << 5], cnt, sum[N << 5], a[N], b[N], c[N], n, q, m; 
inline int read() {
    int x = 0, k = 1; char c = getchar();
    for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    return k ? x : -x;
}
inline int Build(int t, int w) {
    int now = ++cnt, mid = (t + w) >> 1;
    sum[now] = 0;
    if (t < w) {
        l[now] = Build(t, mid);
        r[now] = Build(mid + 1, w);
    }
    return now;
}
inline int add(int k, int t, int w, int x) {
    int now = ++cnt, mid = (t + w) >> 1;
    l[now] = l[k], r[now] = r[k], sum[now] = sum[k] + 1;
    if (t < w && x <= mid)
        l[now] = add(l[k], t, mid, x);
    else if (t < w && x > mid)
        r[now] = add(r[k], mid + 1, w, x);
    return now;
}
inline int ask(int L, int R, int t, int w, int x) {
    if (t >= w)
        return t;
    int mid = (t + w) >> 1, k = sum[l[R]] - sum[l[L]];
    if (k >= x)
        return ask(l[L], l[R], t, mid, x);
    else 
        return ask(r[L], r[R], mid + 1, w, x - k);
}
int main() {
    n = read(), q = read();
    for (int i = 1; i <= n; i++)
        b[i] = a[i] = read();
    std::sort(b + 1, b + 1 + n);
    m = unique(b + 1, b + 1 + n) - b - 1;
    c[0] = Build(1, m);
    for (int i = 1; i <= n; i++) {
        int now = lower_bound(b + 1, b  + 1 + m, a[i]) - b;
        c[i] = add(c[i - 1], 1, m, now);
    }
    for (int i = 1; i <= q; i++) {
        int x = read(), y = read(), z = read();
        printf("%d\n", b[ask(c[x - 1], c[y], 1, m, z)]);
    }
    return 0;
}

Manacher (9.25)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 31000000;
int len, hw[N], ans;
char s[N];
inline void Manacher() {
    int maxright = 0, mid = 0;
    for (int i = 1; i < len; i++) {
        if (i < maxright)
            hw[i] = std::min(hw[(mid << 1) - i], hw[mid] + mid - i);
        else 
            hw[i] = 1;
        while (s[i + hw[i]] == s[i - hw[i]])
            ++hw[i];
        if (hw[i] + i > maxright)
            maxright = hw[i] + i, mid = i;
    }
}
int main() {
    scanf("%s", s + 1);
    len = strlen(s + 1);
    for (int i = len; i >= 1; i--)
        s[i * 2] = s[i];
    s[0] = s[1] = '#';
    for (int i = 1; i <= len; i++)
        s[i * 2 + 1] = '#';
    s[len * 2 + 2] = 0;
    len = len * 2 + 2;
    Manacher();
    ans = 1;
    for (int i = 0; i < len; i++)
        ans = std::max(ans, hw[i]);
    printf("%d\n", ans - 1);
    return 0;
}

线性基 (9.26)

插入、判断、查询最大最小值、查询第\(k\)小值

#include<bits/stdc++.h>
using namespace std;
const int M = 60;
int n;
long long x, a[M + 10], b[M +10];
bool flag;
inline int read() {
    int x = 0, k = 1; char c = getchar();
    for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    return k ? x : -x;
}
inline long long read1() {
    long long x = 0, k = 1; char c = getchar();
    for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    return k ? x : -x;
}
inline void Insert(long long x) {  //插入
    for (int i = M; i >= 0; i--)
        if (x & (1ll << i))
            if (!a[i]) {
                a[i] = x;
                return;
            }
            else x ^= a[i];
    flag = true;
}
inline bool check(long long x) {  //判断
    for (int i = M; i >= 0; i--) 
        if (x & (1ll << i))
            if (!a[i])
                return false;
            else 
                x ^= a[i];
    return true;
}
inline long long Ask_max() {      //查询最大值
    long long maxx = 0;
    for (int i = M; i >= 0; i--)
        maxx = std::max(maxx, maxx ^ a[i]);
    return maxx;
}
inline long long Ask_min() {      //查询最小值
    if (flag)
        return 0;
    for (int i = 0; i <= M; i++)
        if (a[i])
            return a[i];
}
inline long long Ask_kth(long long x) {      //查询第k小值
    long long ans = 0;
    int cnt = 0;
    x -= flag;
    if (!x)
        return 0;
    for (int i = 0; i <= M; i++) {
        for (int j = i - 1; j >= 0; j--) 
            if (a[i] & (1ll << j))
                a[i] ^= a[j];
        if (a[i])
            b[++cnt] = a[i];
    }
    if (x >= (1ll << cnt))
        return -1;
    for (int i = 0; i < cnt; i++)
        if (x & (1ll << i))
            ans ^= b[i];
    return ans;
}
int main() {
    n = read();
    for (int i = 1; i <= n; i++) {
        x = read1();
        Insert(x);
    }
    printf("%lld\n", Ask_max());
    return 0;
}

高斯消元 (9.26)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n;
double a[N][N];
inline bool Gauss(int n, int m) {
    for (int i = 1; i <= n; i++) {
        int maxx = i;
        for (int j = i + 1; j <= n; j++)
            if (fabs(a[j][i]) > fabs(a[maxx][i]))
                maxx = j;
        for (int j = 1; j <= m; j++)
            std::swap(a[i][j], a[maxx][j]);
        if (!a[i][i])
            return false;
        for (int j = 1; j <= n; j++)
            if (j != i) {
                double t = a[j][i] / a[i][i];
                for (int k = i + 1; k <= m; k++)
                    a[j][k] = a[j][k] - a[i][k] * t;
            }
    }
    return true;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n + 1; j++)
            scanf("%lf", &a[i][j]);
    if (!Gauss(n, n + 1))
        return printf("No Solution\n"), 0;
    for (int i = 1; i <= n; i++)
        printf("%.2f\n", a[i][n + 1] / a[i][i]);
    return 0;
}

矩阵求逆 (9.26)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 1010, Mo = 1e9 + 7;
int n, a[N][N];
inline int ksm(int a, int b) {
    int ans = 1;
    for (; b; b >>= 1, a = 1LL * a * a % Mo)
        if (b & 1) ans = 1LL * ans * a % Mo;
    return ans;
}
inline bool Gauss(int n, int m) {
    for (int i = 1; i <= n; i++) {
        int maxx = i;
        for (int j = i + 1; j <= n; j++)
            if (fabs(a[j][i]) > fabs(a[maxx][i]))
                maxx = j;
        if (i != maxx)      
            for (int j = 1; j <= m; j++)
                std::swap(a[i][j], a[maxx][j]);
        if (!a[i][i])
            return false;
        int d = ksm(a[i][i], Mo - 2);
        for (int j = i; j <= m; j++)
            a[i][j] = 1LL * a[i][j] * d % Mo;
        for (int j = 1; j <= n; j++)
            if (j != i) {
                d = a[j][i];
                for (int k = i; k <= m; k++)
                    a[j][k] = (a[j][k] - 1LL * a[i][k] * d % Mo + Mo) % Mo;
            }
    }
    return true;
}
signed main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++)
            scanf("%d", &a[i][j]);
        a[i][n + i] = 1;
    }
    if (!Gauss(n, n + n))
        return printf("No Solution\n"), 0;
    for (int i = 1; i <= n; i++)
        for (int j = n + 1; j <= n + n; j++)
            printf("%d%c", a[i][j], " \n"[j == n + n]);
    return 0;
}

普通莫队 (9.27)

SP3267 DQUERY - D-query

#include<bits/stdc++.h>
using namespace std;
const int N = 3e4 + 10, M = 2e6 + 10;
int n, m, now, be[M], a[M], cnt[M], ans[M];
struct Node {
    int l, r, id;
} q[M];
inline int read() {
    int x = 0, k = 1; char c = getchar();
    for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    return k ? x : -x;
}
inline bool cmp(Node a, Node b) {
    return (be[a.l] ^ be[b.l]) ? be[a.l] < be[b.l] : ((be[a.l] & 1) ? a.r < b.r : a.r > b.r);
} 
int main() {
    n = read();
    int sz = sqrt(n), n1 = ceil((double)n / sz);
    for (int i = 1; i <= n1; i++)
        for (int j = (i - 1) * sz + 1; j <= i * sz; j++)
            be[j] = i;
    for (int i = 1; i <= n; i++)
        a[i] = read();
    m = read();
    for (int i = 1; i <= m; i++)
        q[i].l = read(), q[i].r = read(), q[i].id = i;
    std::sort(q + 1, q + 1 + m, cmp);
    int L = 1, R = 0;
    for (int i = 1; i <= m; i++) {
        int l = q[i].l, r = q[i].r;
        while (L < l)
            now -= !--cnt[a[L++]];
        while (L > l)
            now += !cnt[a[--L]]++;
        while (R < r)
            now += !cnt[a[++R]]++;
        while (R > r)
            now -= !--cnt[a[R--]];
        ans[q[i].id] = now;
    }
    for (int i = 1; i <= m; i++)
        printf("%d\n", ans[i]);
    return 0;
}

带修莫队 (9.27)

题目

#include<bits/stdc++.h>
using namespace std;
const int N = 3e4 + 10, M = 2e6 + 10;
int n, m, now, be[M], a[M], cnt[M], ans[M], cntc, cntq;
char ch;
struct Query {
    int l, r, id, time;
} q[M];
struct Replace {
    int pos, color;
} c[M];
inline int read() {
    int x = 0, k = 1; char c = getchar();
    for (; c < 48 || c > 57; c = getchar()) k ^= (c == '-');
    for (; c >= 48 && c <= 57; c = getchar()) x = x * 10 + (c ^ 48);
    return k ? x : -x;
}
inline bool cmp(Query a, Query b) {
    return (be[a.l] ^ be[b.l]) ? be[a.l] < be[b.l] : ((be[a.r] ^ be[b.r]) ? be[a.r] < be[b.r] : a.time < b.time);
} 
int main() {
    n = read(), m = read();
    int sz = pow(n, 2.0 / 3.0), n1 = ceil((double)n / sz);
    for (int i = 1; i <= n1; i++)
        for (int j = (i - 1) * sz + 1; j <= i * sz; j++)
            be[j] = i;
    for (int i = 1; i <= n; i++)
        a[i] = read();
    for (int i = 1; i <= m; i++) {
        scanf("%c", &ch);
        while (ch != 'Q' && ch != 'R')
            scanf("%c", &ch);
        if (ch == 'Q') {
            q[++cntq].l = read(), q[cntq].r = read(), q[cntq].time = cntc, q[cntq].id = cntq;
        }
        else if (ch == 'R') {
            c[++cntc].pos = read(), c[cntc].color = read();
        }
    }
    std::sort(q + 1, q + 1 + cntq, cmp);
    int L = 1, R = 0, Time = 0;
    for (int i = 1; i <= m; i++) {
        int l = q[i].l, r = q[i].r, time = q[i].time;
        while (L < l)
            now -= !--cnt[a[L++]];
        while (L > l)
            now += !cnt[a[--L]]++;
        while (R < r)
            now += !cnt[a[++R]]++;
        while (R > r)
            now -= !--cnt[a[R--]];
        while (Time < time) {
            Time++;
            if (l <= c[Time].pos && r >= c[Time].pos)
                now -= !--cnt[a[c[Time].pos]] - !cnt[c[Time].color]++;
            std::swap(a[c[Time].pos], c[Time].color);
        }
        while (Time > time) {
            if (l <= c[Time].pos && r >= c[Time].pos)
                now -= !--cnt[a[c[Time].pos]] - !cnt[c[Time].color]++;
            std::swap(a[c[Time].pos], c[Time].color);
            Time--;
        }
        ans[q[i].id] = now;
    }
    for (int i = 1; i <= cntq; i++)
        printf("%d\n", ans[i]);
    return 0;
}

WQS 二分 (未)

学习链接

转载于:https://www.cnblogs.com/wjnclln/p/11585442.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值