cf896C. Willem, Chtholly and Seniorious(ODT)

自為風月馬前卒發表於2019-02-09

題意

題目連結

Sol

ODT板子題。就是用set維護連續段的大暴力。。

然鵝我抄的板子本題RE提交AC??。。

具體來說,用50 50 658073485 946088556這個資料測試下面的程式碼,然後在79行停住,看一下bg和i的值會發生神奇的事情。。

問題已解決,確實是那位博主寫錯了, 只要把split(l)和split(r + 1)反過來就行了

#include<bits/stdc++.h>
#define LL long long 
#define int long long 
#define sit set<Node>::iterator 
#define fi first
#define se second 
using namespace std;
const int MOD = 1e9 + 7, MAXN = 1e6 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < `0` || c > `9`) {if(c == `-`) f = -1; c = getchar();}
    while(c >= `0` && c <= `9`) x = x * 10 + c - `0`, c = getchar();
    return x * f;
}
int N, M, mod;
template<typename A, typename B> inline int mul(A x, B y) {
    return 1ll * x * y % mod;
}
template<typename A, typename B> inline void add2(A &x, B y) {
    x = (x + y % mod);
}
LL seed, vmax;
int a[MAXN];
int rnd() {
    int ret = seed;
    seed = (seed * 7 + 13) % MOD;
    return ret;
}
struct Node {
    int l, r;
    mutable LL v;
    bool operator < (const Node &rhs) const {
        return l < rhs.l;
    }
};
set<Node> s;
sit split(int p) {
    auto pos = s.lower_bound({p});
    if(pos != s.end() && pos->l == p) return pos; 
    pos--;
    int L = pos->l, R = pos->r, V = pos->v;
    s.erase(pos);
    s.insert({L, p - 1, V}); 
    return s.insert({p, R, V}).fi;
}
void Add(int l, int r, int val) {
    auto bg = split(l), ed = split(r + 1);
    for(auto i = bg; i != ed; i++) i->v += val;
}
void Mem(int l, int r, int val) {
    for(int i = l; i <= r; i++) a[i] = val;
    auto bg = split(l), ed = split(r + 1);
    s.erase(bg, ed);
    s.insert({l, r, val});
}
int rak(int l, int r, int x) {
    vector<pair<LL, int>> v;
    auto bg = split(l), ed = split(r + 1);
    for(auto i = bg; i != ed; i++) 
        v.push_back({i->v, i->r - i->l + 1});   

    sort(v.begin(), v.end());
    for(auto it = v.begin(); it != v.end(); it++) {
        x -= it -> se;
        if(x <= 0) return it -> fi;
    }
    assert(0);
}
int fp(int a, int p) {
    int base = 1; a %= mod;
    while(p) {
        if(p & 1) base = 1ll * base * a % mod;
        a = 1ll * a * a % mod; p >>= 1;
    }
    return base;
}
int po(int l, int r, int x) {
    if(l == 6 && r == 7) {
        puts("G");
    }
    auto bg = split(l);
    printf("%d %d %d %d
", bg->l, bg->r, bg->v);
    auto ed = split(r + 1);
    int ans = 0;
    for(sit i = bg; i != ed; i++) {
        printf("%d %d %d %d
", i->l, i->r, i->v);
        ans = (ans + (i->r - i->l + 1) * fp(i->v, x) % mod) % mod;
    }
    return ans;
}
signed main() {
    N = read(); M = read(); seed = read(); vmax = read();
    for(int i = 1; i <= N; i++) a[i] = (rnd() % vmax) + 1, s.insert({i, i, a[i]});
    s.insert({N + 1, N + 1, 0});
    for(int i = 1; i <= M; i++) {
        int op = (rnd() % 4) + 1; int l = (rnd() % N) + 1; int r = (rnd() % N) + 1, x = -1;
        if(l > r) swap(l, r);
        
        if(op == 3) x = (rnd() % (r - l + 1)) + 1;
        else x = (rnd() % vmax) + 1;
        if(op == 4) mod = (rnd() % vmax) + 1; 
        if(op == 1) Add(l, r, x);
        else if(op == 2) Mem(l, r, x);
        else if(op == 3) cout << rak(l, r, x) << `
`;
        else cout << po(l, r, x) << `
`;
    }
    return 0;
}
/*
50 50 658073485 946088556
*/