「TJOI2019」甲苯先生的滚榜

Posted zsbzsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「TJOI2019」甲苯先生的滚榜相关的知识,希望对你有一定的参考价值。

「TJOI2019」甲苯先生的滚榜

传送门
双关键字感觉不太好搞?直接压成一个 long long 就好了呗。
然后就是平衡树板子了。
参考代码:

#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
#define LL long long 
using namespace std;

template < class T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while ('0' > c || c > '9') f |= c == '-', c = getchar();
    while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
    s = f ? -s : s;
}

typedef unsigned int ui;
ui seed, last = 7;
inline ui randNum(const ui m) {
    seed = seed * 17 + last;
    return seed % m + 1;
}

const int _ = 1e6 + 5;

int T, n, m, rt, tot, siz[_], pri[_], ch[2][_]; LL val[_], w[_];

inline int Newnode(LL v)
{ return siz[++tot] = 1, pri[tot] = rand(), val[tot] = v, tot; }

inline void pushup(int p) { siz[p] = siz[ch[0][p]] + siz[ch[1][p]] + 1; }

inline int merge(int x, int y) {
    if (!x || !y) return x + y;
    if (pri[x] > pri[y])
        return ch[1][x] = merge(ch[1][x], y), pushup(x), x;
    else
        return ch[0][y] = merge(x, ch[0][y]), pushup(y), y;
}

inline void split(int p, LL v, int& x, int& y) {
    if (!p) { x = y = 0; return ; }
    if (val[p] <= v)
        return x = p, split(ch[1][p], v, ch[1][x], y), pushup(p);
    else
        return y = p, split(ch[0][p], v, x, ch[0][y]), pushup(p);
}

inline void erase(LL v) {
    int a, b, c;
    split(rt, v, a, c);
    split(a, v - 1, a, b);
    b = merge(ch[0][b], ch[1][b]);
    rt = merge(a, merge(b, c));
}

inline void insert(LL v) {
    int a, b;
    split(rt, v, a, b);
    rt = merge(a, merge(Newnode(v), b));
}

inline int rank(LL v) {
    int a, b, res;
    split(rt, v - 1, a, b);
    res = siz[a];
    rt = merge(a, b);
    return res;
}

inline void init() {
    rt = tot = 0;
    memset(w, 0, sizeof w);
    memset(ch, 0, sizeof ch);
    memset(siz, 0, sizeof siz);
    memset(pri, 0, sizeof pri);
    memset(val, 0, sizeof val); 
}

int main() {
    read(T);
    while (T--) {
        init();
        read(m), read(n), read(seed);
        for (rg int a, b; n--; ) {
            int ria = randNum(m), rib = randNum(m);
            erase(w[ria]);
            w[ria] += rib - 1500000;
            insert(w[ria]);
            last = rank(w[ria]);
            printf("%d
", last);
        }
    }
    return 0;
}

以上是关于「TJOI2019」甲苯先生的滚榜的主要内容,如果未能解决你的问题,请参考以下文章

luogu P5338 [TJOI2019]甲苯先生的滚榜

[TJOI2019]甲苯先生和大中锋的字符串

p5341 [TJOI2019]甲苯先生和大中锋的字符串

[TJOI2019]甲苯先生和大中锋的字符串

题解Luogu P5337 [TJOI2019]甲苯先生的字符串

TJOI2019甲苯先生和大中锋的字符串