代码
// Problem: E. Willem, Chtholly and Seniorious
// Contest: Codeforces Round #449 (Div. 2)
// URL: https://codeforces.com/contest/897/problem/E
// Memory Limit: 256 MB
// Time Limit: 2000 ms
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#define rep(i,a,b) for(int i = a; i <= b; ++i)
#define per(i,a,b) for(int i = a; i >= b; --i)
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define pii pair<int,int>
#define ll long long
using namespace std;
const int N = (int)(1e5 + 10);
const int mod = 1e9 + 7;
const int modm = 299987;
const int INF = 0x3f3f3f3f;
inline ll read() {
ll p = 0; int f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
p = (p << 3) + (p << 1) + ch - '0';
ch = getchar();
}
return p*f;
}
struct node {
mutable ll v;
int l, r;
bool operator <(const node &x) const {
return l < x.l;
}
node(int l, int r, ll v) : l(l),r(r),v(v) {}
node(int l) : l(l) {}
};
set<node> se;
#define sit set<node>::iterator
sit split(int pos) {
sit it = lower_bound(se.begin(), se.end(), node(pos));
if(it != se.end() && it->l == pos) return it;
--it;
int l = it->l, r = it->r;
ll v = it -> v;
se.erase(it);
se.insert(node(l, pos - 1, v));
return se.insert(node(pos, r, v)).fi;
}
void assign(int l, int r, ll v) {
sit itr = split(r + 1), itl = split(l);
se.erase(itl, itr);
se.insert(node{l, r, v});
}
void add(int l, int r, ll v) {
sit itr = split(r + 1), itl = split(l);
for(sit it = itl; it != itr; ++it) it->v += v;
}
ll kth_min(int l, int r, int k) {
sit itr = split(r + 1), itl = split(l);
vector<pair<ll, int>> vec;
for(sit it = itl; it != itr; ++ it) {
vec.pb(mp(it->v, it->r - it->l + 1));
}
sort(vec.begin(), vec.end());
for(auto it : vec) {
k -= it.se;
if(k <= 0) return it.fi;
}
}
ll ksm(ll a, int x, ll y) {
ll res = 1ll;
a %= y;
while(x) {
if(x & 1) res = (res * a) % y;
a = (a * a) % y;
x >>= 1;
}
return res;
}
ll query(int l, int r, int x, ll y) {
sit itr = split(r + 1), itl = split(l);
ll res = 0;
for(sit it = itl; it != itr; ++it) {
res = (res + (it->r - it->l + 1) * ksm(it->v, x, y)) % y;
}
return res;
}
int n, m, vmax;
ll seed;
int rnd() {
int ret = (int)seed;
seed = (seed * 7 + 13 ) % 1000000007;
return ret;
}
int main() {
n = (int)read();
m = (int)read();
seed = read();
vmax = (int)read();
rep(i,1,n) {
int a = rnd() % vmax + 1;
se.insert(node(i,i,a));
}
se.insert(node(n + 1, n + 1, 0));
rep(i,1,m) {
int op = (rnd() % 4) + 1;
int l = (rnd() % n) + 1;
int r = (rnd() % n) + 1;
int x, y;
ll res = 0;
if(l > r) swap(l, r);
if(op == 3) {
x = (rnd() % (r - l + 1)) + 1;
} else {
x = (rnd() % vmax) + 1;
}
if(op == 4) {
y = (rnd() % vmax) + 1;
}
if(op == 1) add(l, r, x);
else if(op == 2) assign(l, r, x);
else if(op == 3) printf("%lld\n", kth_min(l, r, x));
else if(op == 4) printf("%lld\n", res = query(l, r, x, y));
}
return 0;
}