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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| #include <cstdio> #include <set> #include <vector> #include <algorithm> #define It set<node>::iterator
typedef long long ll; using namespace std;
const ll mod7 = 1e9 + 7; const ll N = 1e5 + 1; ll n, m, seed, vmax; ll a[N];
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; } };
set<node> tree;
inline ll qpow (ll x, ll p, ll mod) { ll res = 1; ll ans = x % mod; while (p) { if (p & 1) res = res * ans % mod; ans = ans * ans % mod; p >>= 1; } return res; }
It split (ll pos) { It it = tree.lower_bound (node (pos, 0, 0)); if (it != tree.end () && it -> l == pos) return it; it --; ll l = it -> l, r = it -> r, v = it -> v; tree.erase (it); tree.insert (node (l, pos - 1, v)); return tree.insert (node (pos, r, v)).first; }
void add (ll l, ll r, ll v) { It end = split (r + 1); for (It it = split (l); it != end; it ++) it -> v += v; }
void assign (ll l, ll r, ll v) { It end = split (r + 1), begin = split (l); tree.erase (begin, end); tree.insert (node (l, r, v)); }
ll rankk (ll l, ll r, ll k) { It end = split (r + 1); vector <pair<ll, ll> > v; for (It it = split (l); it != end; it ++) v.push_back (make_pair (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 sum_pow (ll l, ll r, ll p, ll mod) { ll tot = 0; It end = split (r + 1); for (It it = split (l); it != end; it ++) tot = (tot + qpow (it -> v, p, mod) * (it -> r - it -> l + 1)) % mod; return tot; }
ll rnd () { ll ret = seed; seed = (seed * 7 + 13) % mod7; return ret; }
signed main () { scanf ("%lld %lld %lld %lld", &n, &m, &seed, &vmax); for (int i = 1; i <= n; i ++) { a[i] = (rnd () % vmax) + 1; tree.insert (node (i, i, a[i])); } tree.insert (node (n + 1, n + 1, 0)); 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 = int (rnd () % (r - l + 1)) + 1; else x = int (rnd () % vmax) + 1; if (op == 4) y = int (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", rankk (l, r, x)); else printf ("%lld\n", sum_pow (l, r, x, y)); } return 0; }
|