CF896C Willem, Chtholly and Seniorious 珂朵莉树

CF896C Willem, Chtholly and Seniorious 珂朵莉树

不管毒瘤出题人卡不卡珂朵莉树我都永远喜欢珂朵莉。

传送门还是扔洛谷的算了

就当存个好看的板子,放上有注释的代码。

总之记住看见数据随机想想珂朵莉树总没错。

不要问我为什么代码长得和洛谷第一篇题解那么像,你以为我是从哪里学的?

#include <cstdio>
#include <set>
#include <algorithm>
#include <vector>
#define R register
#define I inline
#define L long long
#define IT set <node> :: iterator//敢用auto?
using namespace std;
const int N = 100003, yyb = 1e9 + 7;//yyb还是要膜的
L seed, vmax;
I L random() {
    L x = seed;
    seed = (seed * 7 + 13) % yyb;
    return x;
}//数据生成器,等于告诉你这是随机数据,可以珂朵莉树艹过去
L power(L a, L b, L mod) {
    L r = 1;
    for (a = a % mod; b; a = a * a % mod, b = b >> 1)//a = a % mod,你可以不加试试
        if (b & 1)
            r = r * a % mod;
    return r;
}
struct node {
    int l, r;
    mutable L v;
    node(int _l, int _r = -1, L _v = 0) : l(_l), r(_r), v(_v) {}
    int operator < (const node &y) const { return l < y.l; }//存进set
};
set <node> c;
I IT split(int x) {//一个区间拆成两个
    IT i = c.lower_bound(node(x));//找到
    if (i != c.end() && i->l == x)//不用拆
        return i;
    --i;//要拆的在前面一个区间
    R int l = i->l, r = i->r;
    L v = i->v;
    c.erase(i), c.insert(node(l, x - 1, v));//拆了
    return c.insert(node(x, r, v)).first;//插入,顺便返回迭代器
}
I void modify(int l, int r, L v) {//区间加,大暴力
    IT il = split(l), ir = split(r + 1);
    for (; il != ir; ++il)
        il->v += v;
}
I void assign(int l, int r, L v) {//推平,大暴力,复杂度的保证
    IT il = split(l), ir = split(r + 1);
    c.erase(il, ir), c.insert(node(l, r, v));
}
I void kth(int l, int r, int k) {//第K大,大暴力
    vector <pair <L, int> > vec;//暴力开啊
    vec.clear();
    IT il = split(l), ir = split(r + 1);
    for (; il != ir; ++il)
        vec.push_back(make_pair(il->v, il->r - il->l + 1));
    sort(vec.begin(), vec.end());//全丢进来排序
    for (R int i = 0, m = vec.size(); i < m; ++i) {//暴力啊
        k -= vec[i].second;
        if (k <= 0) {
            printf("%I64d\n", vec[i].first);
            return ;
        }
    }
    printf("-1\n");
}
I void query(int l, int r, int ex, int mod) {//查询ex次方,大暴力
    IT il = split(l), ir = split(r + 1);
    L o = 0;
    for (; il != ir; ++il)
        o = (o + power(il->v, ex, mod) * (il->r - il->l + 1)) % mod;
    printf("%I64d\n", o);
}
int main() {
    R int n, m, i, l, r, o, x, y;
    scanf("%d%d%I64d%I64d", &n, &m, &seed, &vmax);
    for (i = 1; i <= n; ++i)
        x = random() % vmax + 1, c.insert(node(i, i, x));
    c.insert(node(n + 1, n + 1, 0));
    for (i = 1; i <= m; ++i) {
        o = random() % 4 + 1, l = random() % n + 1, r = random() % n + 1;
        if (r < l)
            swap(l, r);
        if (o == 3)
            x = random() % (r - l + 1) + 1;
        else
            x = random() % vmax + 1;
        if (o == 4)
            y = random() % vmax + 1;
        switch (o) {//switch真长
        case 1: {
            modify(l, r, x);
            break;
        }
        case 2: {
            assign(l, r, x);
            break;
        }
        case 3: {
            kth(l, r, x);
            break;
        }
        case 4: {
            query(l, r, x, y);
            break;
        }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/cj-chd/p/10296931.html