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; }
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; }
|