CF896C Willem, Chtholly and Seniorious(珂朵莉树)
这还需要题解?分段!区间代替点!暴力出奇迹!
#include <cstdio>
#include <cstring>
#include <numeric>
#include <cmath>
#include <algorithm>
#include <iostream>
#define R(a,b,c) for(register int a = (b); a <= (c); ++a)
#define nR(a,b,c) for(register int a = (b); a >= (c); --a)
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define MP make_pair
#ifdef QWQ
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#define D_e_Line cerr << "\n--------\n"
#define D_e(x) cerr << (#x) << " : " << x << endl
#define C_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define TIME() fprint(stderr, "TIME : %.3lfms\n", (double)clock() / (double)CLOCKS_PER_SEC)
#else
#define FileOpen()
#define FileSave()
#define D_e_Line
#define D_e(x)
#define C_e(x)
#define Pause()
#define TIME()
#endif
struct FastIO {
template<typename ATP> inline FastIO & operator >> (ATP & x) {
x = 0; int f = 1; char c;
for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') f = -1;
while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
if(f == -1) x = -x;
return *this;
}
} io;
using namespace std;
template<typename ATP> inline ATP Max(ATP x, ATP y) {
return x > y ? x : y;
}
template<typename ATP> inline ATP Min(ATP x, ATP y) {
return x < y ? x : y;
}
template<typename ATP> inline ATP Abs(ATP x) {
return x > 0 ? x : -x;
}
#include<set>
#include<vector>
const int MOD = 1e9 + 7;
const int N = 1e5 + 7;
struct nod {
int l, r;
mutable long long val;
nod() {}
nod(int _l, int _r = -1, long long _val = 0) : l(_l), r(_r), val(_val) {}
bool operator < (const nod &rhs) const {
return l < rhs.l;
}
};
set<nod> S;
set<nod>::iterator Split(int pos) {
set<nod>::iterator it = S.lower_bound(nod(pos));
if(it != S.end() && it->l == pos) return it;
--it;
int r = it->r, l = it->l;
long long val = it->val;
S.erase(it);
S.insert(nod(l, pos - 1, val));
return S.insert(nod(pos, r, val)).first;
}
inline void Assign(int l, int r, long long val = 0) {
set<nod>::iterator R = Split(r + 1), L = Split(l);
S.erase(L, R);
S.insert(nod(l, r, val));
}
inline void Add(int l, int r, long long val = 1) {
set<nod>::iterator R = Split(r + 1), L = Split(l);
for(; L != R; ++L) L->val += val;
}
inline long long Rank(int l, int r, int K) {
vector<pair<long long, int> > V;
set<nod>::iterator R = Split(r + 1), L = Split(l);
V.clear();
for(; L != R; ++L) V.push_back(MP(L->val, L->r - L->l + 1));
sort(V.begin(), V.end());
for(vector<pair<long long, int> >::iterator it = V.begin(); it != V.end(); ++it){
K -= it->second;
if(K <= 0) return it->first;
}
return -1ll;
}
inline long long Pow(long long a, int b, int &mod) {
long long s = 1;
a %= mod;
while(b){
if(b & 1) s = s * a % mod;
a = a * a % mod, b >>= 1;
}
return s;
}
inline long long Sum(int l, int r, int ex, int mod) {
set<nod>::iterator R = Split(r + 1), L = Split(l);
long long sum = 0;
for(; L != R; ++L){
sum = (sum + 1ll * (L->r - L->l + 1) * Pow(L->val, ex, mod)) % mod;
}
return sum;
}
int n, m;
long long seed, vmax;
inline long long rnd() {
long long ret = seed;
seed = (seed * 7 + 13) % MOD;
return ret;
}
long long a[N];
int main(){
FileOpen();
io >> n >> m >> seed >> vmax;
R(i,1,n){
a[i] = (rnd() % vmax) + 1;
S.insert(nod(i, i, a[i]));
}
S.insert(nod(n + 1, n + 1, 0));
R(i,1,m){
int opt = rnd() % 4 + 1, l = rnd() % n + 1, r = rnd() % n + 1;
if(l > r) Swap(l, r);
int x, y;
if(opt == 3){
x = rnd() % (r - l + 1) + 1;
}
else{
x = rnd() % vmax + 1;
}
if(opt == 4){
y = rnd() % vmax + 1;
}
if(opt == 1)
Add(l, r, x);
else if (opt == 2)
Assign(l, r, x);
else if (opt == 3)
printf("%lld\n", Rank(l, r, x));
else
printf("%lld\n", Sum(l, r, x, y));
}
return 0;
}