CodeForces 896C Willem, Chtholly and Seniorious

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;
using LL = long long;
struct Node {
LL l, r;
mutable LL v;
Node(LL l, LL r, LL v) : l(l), r(r), v(v) {}
bool operator <(const Node &o) const {
return l < o.l;
}
};
LL n, m, seed, vmax;
set<Node> tree;
LL rnd() {
LL ans = seed;
seed = (seed * 7 + 13) % 1000000007;
return ans;
}
LL qpow(LL a, LL k, LL p) {
LL ans = 1;
a %= p;
while (k) {
if (k & 1)
ans = ans * a % p;
k >>= 1;
a = a * a % p;
}
return ans;
}
// if pos isn't a range start, then split its range from pos into [l, pos - 1], [pos, r].
set<Node>::iterator split(LL pos) {
auto it = tree.lower_bound({pos, 0, 0});
if (it != tree.end() && it->l == pos)
return it;
--it;
auto [l, r, v] = *it;
tree.erase(it);
tree.insert({l, pos - 1, v});
return tree.insert({pos, r, v}).first;
}
void add(LL l, LL r, LL v) {
auto end = split(r + 1);
for (auto it = split(l); it != end; ++it)
it->v += v;
}
void assign(LL l, LL r, LL v) {
auto end = split(r + 1), begin = split(l);
tree.erase(begin, end);
tree.insert({l, r, v});
}
LL kth(LL l, LL r, LL k) {
auto end = split(r + 1);
vector<pair<LL, LL>> v;
for (auto it = split(l); it != end; ++it)
v.emplace_back(it->v, it->r - it->l + 1);
sort(v.begin(), v.end());
for (int i = 0; i < v.size(); ++i) {
k -= v[i].second;
if (k <= 0)
return v[i].first;
}
}
LL sumOfPow(LL l, LL r, LL x, LL y) {
LL tot = 0;
auto end = split(r + 1);
for (auto it = split(l); it != end; ++it)
tot = (tot + qpow(it->v, x, y) * (it->r - it->l + 1)) % y;
return tot;
}
int main(void) {
scanf("%lld%lld%lld%lld", &n, &m, &seed, &vmax);
for (int i = 1; i <= n; ++i) {
int r = rnd();
tree.insert({i, i, r % vmax + 1});
}
for (int i = 1; i <= m; ++i) {
LL op = rnd() % 4 + 1, l = rnd() % n + 1, r = rnd() % n + 1, x, y;
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;
switch (op) {
case 1:
add(l, r, x);
break;
case 2:
assign(l, r, x);
break;
case 3:
printf("%lld\n", kth(l, r, x));
break;
case 4:
printf("%lld\n", sumOfPow(l, r, x ,y));
}
}
return 0;
}