• BZOJ5509: [Tjoi2019]甲苯先生的滚榜


    题解

    开n个平衡树对每个AC数维护罚时,然后不同AC数用树状数组维护即可。
    其实挺好写的...就是评测的时候评的巨久...

    #include <bits/stdc++.h>
    using namespace std;
     
    typedef long long ll;
    const int N = 1000010;
     
    int T, n, m, cnt[N], tim[N];
     
    namespace Rand {
    typedef unsigned int ui;
    ui seed;
    ui randNum(ui& seed, ui last, const ui m) {
        seed = seed * 17 + last;
        return seed % m + 1;
    }
    }
    namespace fhqtreap {
    int root[N], tot;
    struct treap {int lc, rc, val, rnd, siz;} t[N<<2];
    void clear() {memset(root, 0, sizeof(root)); tot = 0;}
    void up(int rt) {t[rt].siz = t[t[rt].lc].siz + t[t[rt].rc].siz + 1;}
    int build(int val) {
        t[++tot] = (treap) {0, 0, val, rand()<<15|rand(), 1};
        return tot;
    }
    void split(int rt, int &l, int &r, int c) {
        if(!rt) l = r = 0;
        else if(t[rt].val <= c) split(t[l = rt].rc, t[rt].rc, r, c), up(rt);
        else split(t[r = rt].lc, l, t[rt].lc, c), up(rt);
    }
    void merge(int &rt, int l, int r) {
        if(!l || !r) rt = l + r;
        else if(t[l].rnd < t[r].rnd) rt = l, merge(t[rt].rc, t[rt].rc, r), up(rt);
        else rt = r, merge(t[rt].lc, l, t[rt].lc), up(rt);
    }
    void insert(int id, int val) {
        int x, y, z = build(val); 
        split(root[id], x, y, val);
        merge(x, x, z); merge(root[id], x, y);
    }
    void Del(int id, int val) {
        int x, y, z;
        split(root[id], x, y, val);
        split(x, x, z, val - 1);
        merge(z, t[z].lc, t[z].rc);
        merge(x, x, z); merge(root[id], x, y);
    }
    int rnk(int rt, int val) {
        if(!rt) return 0;
        if(t[rt].val >= val) return rnk(t[rt].lc, val);
        return rnk(t[rt].rc, val) + t[t[rt].lc].siz + 1;
    }
    }
    namespace BIT {
    int c[N];
    #define lowbit(i) (i & -i)
    void clear() {memset(c, 0, sizeof(c));}
    void add(int x, int v) {for(int i = x; i <= n; i += lowbit(i)) c[i] += v;}   
    int query(int x) {int ans = 0; for(int i = x; i; i -= lowbit(i)) ans += c[i]; return ans;}
    }
     
    int main() {
        int ans = 7; scanf("%d", &T); while(T--) {
        fhqtreap::clear(); BIT::clear(); 
        memset(cnt, 0, sizeof(cnt)); memset(tim, 0, sizeof(tim));
        scanf("%d%d%u", &m, &n, &Rand::seed);
        for(int i = 1; i <= n; ++i) {
            int Ria = Rand::randNum(Rand::seed, ans, m);
            int Rib = Rand::randNum(Rand::seed, ans, m);
            if(cnt[Ria]) {
                fhqtreap::Del(cnt[Ria], tim[Ria]);
                BIT::add(cnt[Ria], -1);
            }
            tim[Ria] += Rib; ++cnt[Ria];
            BIT::add(cnt[Ria], 1);
            fhqtreap::insert(cnt[Ria], tim[Ria]);
            ans = fhqtreap::rnk(fhqtreap::root[cnt[Ria]], tim[Ria]) + BIT::query(n) - BIT::query(cnt[Ria]);
            printf("%d
    ", ans);
        }}
        return 0;
    }
    
  • 相关阅读:
    一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    常用Flex 布局scss
    设置npm registry的几种方法
    JavaScript计算平方数的三种方法
    NPM 使用介绍
    x 的 y次幂科学计数法
    Docker 容器使用
    使用dos的tree命令输出文件夹树
    赣州(虔州)历史文化
    vue通过$ref获取不到元素样式?
  • 原文地址:https://www.cnblogs.com/henry-1202/p/11849243.html
Copyright © 2020-2023  润新知