首页 > 技术文章 > [TJOI2019]总结

ac-evil 2020-03-26 08:40 原文

(好像题目都比较水)

甲苯先生的字符串

  算法:DP,矩阵

  显然DP。设字符集大小为size,直接搞显然\(\mathcal O(size^2n)\)。用矩阵加速,复杂度\(\mathcal O(size^3\log_2n)\)

甲苯先生的滚榜

  算法:平衡树或线段树

  板子题。直接上平衡树模拟,复杂度\(\mathcal O(n\log n)\)。或者常数小的,用线段树配合线段树(有点像树套树,但不一样),分别维护第一关键字和第二关键字,第一关键字可以用树状数组,第二关键字用动态开点线段树,复杂度同上。

#include <bits/stdc++.h>

#define rep(i, a, b) for (int i = a, i##end = b; i <= i##end; ++i)

const int maxn = 100000 + 5, maxm = 1000000 + 5, size = 1500000 + 5;

int n, m, lastans = 7;
unsigned int seed;
int randNum() {
    seed = seed * 17 + lastans;
    return seed % n + 1;
}

namespace SGT {
    struct Node {
        int l, r, v;
        Node() : l(0), r(0), v(0) {};
    } node[maxm*21];
#define ls node[o].l
#define rs node[o].r
    int pt;
    void clear() { pt = 0; }
    void modify(int &o, int l, int r, int p, int v) {
        if (!o) node[o = ++pt] = Node();
        node[o].v += v;
        if (l == r) return;
        int mid = l+r>>1;
        if (p <= mid) modify(ls, l, mid, p, v);
        else modify(rs, mid+1, r, p, v);
    }
    int query(int o, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return node[o].v;
        int mid = l+r>>1, res = 0;
        if (ql <= mid) res += query(ls, l, mid, ql, qr);
        if (mid < qr) res += query(rs, mid+1, r, ql, qr);
        return res;
    }
}

int rt[maxm];

namespace BIT {
#define lb(x) (x & (-x))
    int C[maxm];
    void clear() { memset(C, 0, sizeof C); }
    void modify(int i, int v) {
        for (; i <= m+1; i += lb(i)) C[i] += v;
    }
    int query(int i) {
        int res = 0;
        for (; i; i -= lb(i)) res += C[i];
        return res;
    }
}

int ac[maxn], tme[maxn];

void modify(int x, int v) {
    BIT::modify(ac[x]+1, v);
    SGT::modify(rt[ac[x]], 0, size, tme[x], v);
}

int query(int x) {
    return BIT::query(m+1) - BIT::query(ac[x]+1) + (tme[x] ? SGT::query(rt[ac[x]], 0, size, 0, tme[x]-1) : 0);
}

int main() {
    for (int T = read(); T; T--) {
        n = read(), m = read(), seed = read();
        SGT::clear(); BIT::clear();
        rep(i, 0, m) rt[i] = 0;
        rep(i, 1, n) ac[i] = tme[i] = 0, modify(i, 1);
        rep(i, 1, m) {
            int x = randNum(), y = randNum();
            modify(x, -1); ac[x]++; tme[x] += y; modify(x, 1);
            printf("%d\n", lastans = query(x));
        }
    }
    return 0;
}

唱、跳、rap和篮球

  算法:容斥+DP+NTT优化

  (坑坑坑)

推荐阅读