锰锌求助fhq-Treap保林了
查看原帖
锰锌求助fhq-Treap保林了
483928
Z1qqurat楼主2023/6/21 10:53

具体就是那个维护一个 1500000 进制的两位数的做法,然后可以过样例但是前9个点WA了最后一个点甚至TLE。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <ctime>
#define int long long
using namespace std;
const int N = 1.5e6, base = 150000;
int t, n, tot, root, m, pe[N], pr[N];
typedef unsigned int ui ;
ui seed, last = 7;
ui randNum( ui& seed , ui last , const ui m){ 
    seed = seed * 17 + last ; return seed % m + 1; 
}

struct node{
    int prob, pena, val, rk, ls, rs, sz;
}tr[N];

inline void write(int x) {
	if(x < 10) {
		putchar(x + 48);
		return;
	}
	write( x / 10), write(x % 10);
    return ;
}

int new_node(int pb, int pa) {
    tr[++tot].prob = pb;
    tr[tot].pena = base - pa;
    tr[tot].val = base * pb + tr[tot].pena;
    tr[tot].rk = rand();
    tr[tot].sz = 1;
    tr[tot].ls = tr[tot].rs = 0;
    return tot;
}

void update(int k) {
    tr[k].sz = tr[tr[k].ls].sz + tr[tr[k].rs].sz + 1;
    return ;
}

void split(int k, int &a, int &b, int vl) {
    if(!k) {
        a = b = 0;
        return ;
    }
    else if(tr[k].val <= vl) {
        a = k;
        split(tr[k].rs, tr[k].rs, b, vl);
    }
    else {
        b = k;
        split(tr[k].ls, a, tr[k].ls, vl);
    }
    update(k);
    return ;
}

void merge(int &k, int a, int b) {
    if(!a || !b) {
        k = a + b;
        return ;
    }
    else if(tr[a].rk >= tr[b].rk) {
        k = a;
        merge(tr[a].rs, tr[a].rs, b);
    }
    else {
        k = b;
        merge(tr[b].ls, a, tr[b].ls);
    }
    update(k);
    return ;
}

void insert(int &k, int pb, int pa) {
    int a = 0, b = 0, cur = new_node(pb, pa);
    split(k, a, b, tr[cur].val);
    merge(a, a, cur);
    merge(k, a, b);
    return ;
}

void del(int &k, int vl) {
    int a = 0, b = 0, z = 0;
    split(k, a, b, vl);
    split(a, a, z, vl - 1);
    merge(z, tr[z].ls, tr[z].rs);
    merge(a, a, z);
    merge(k, a, b);
    return ;
}

int find_rank(int &k, int vl) {
    int a = 0, b = 0, ret = 0;
    split(k, a, b, vl);
    ret = tr[b].sz;
    merge(k, a, b);
    return ret;
}

signed main() {
    srand(time(0));
    cin >> t;
    while(t--) {
        tot = root = 0;
        cin >> m >> n >> seed;
        for (int i = 1; i <= m; ++i) {
            pe[i] = pr[i] = 0;
            insert(root, pr[i], pe[i]);
        }
        for (int i = 1; i <= n; ++i) {
            int u = randNum(seed, last, m), v = randNum(seed, last, m);
            // cout << u << ' ' << v << ' ' << pr[u] * base + (base - pe[u]) << "\n";
            del(root, pr[u] * base + (base - pe[u]));
            pr[u]++, pe[u] += v;
            insert(root, pr[u], pe[u]);
            last = find_rank(root, tr[tot].val);
            write(last);
            puts("");
        }
    }
    return 0;
}
2023/6/21 10:53
加载中...