解题报告 『CF896C Willem, Chtholly and Seniorious(ODT)』
国内珂朵莉树的起源,同时也是板子题。
网上就能找到很多资料,在此我就不赘述了。
代码实现如下:
#include <bits/stdc++.h> using namespace std; #define int long long #define IT set<node>::iterator #define rep(i, a, b) for (register int i = (a); i <= (b); i++) const int mod7 = 1e9 + 7, maxn = 1e5 + 5; int n, m, seed, vmax; int a[maxn]; vector< pair<int, int> > v; struct node { int l, r; mutable int v; node(int L, int R = -1, int V = 0): l(L), r(R), v(V) {} int operator <(const node &o) const { return l < o.l; } }; set<node> s; int read() { int x = 0, flag = 0; char ch = ' '; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if (ch == '-') { flag = 1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar(); } return flag ? -x : x; } int rnd() { int ret = seed; seed = (seed * 7 + 13) % mod7; return ret; } int quick_power(int a, int b, int mod) { int ans = 1, base = a % mod; while (b > 0) { if (b & 1) { ans *= base; ans %= mod; } b >>= 1; base *= base; base %= mod; } return ans %= mod; } IT split(int pos) { IT it = s.lower_bound(node(pos)); if (it != s.end() && it->l == pos) return it; it--; int L = it->l, R = it->r, V = it->v; s.erase(it); s.insert(node(L, pos - 1, V)); return s.insert(node(pos, R, V)).first; } void add(int l, int r, int val) { IT itr = split(r + 1), itl = split(l); while (itl != itr) { itl->v += val; itl++; } } void assign(int l, int r, int val) { IT itr = split(r + 1), itl = split(l); s.erase(itl, itr); s.insert(node(l, r, val)); } int kth(int l, int r, int k) { IT itr = split(r + 1), itl = split(l); v.clear(); while (itl != itr) { v.push_back(pair<int, int>(itl->v, itl->r - itl->l + 1)); itl++; } sort(v.begin(), v.end()); for (vector< pair<int, int> >::iterator it = v.begin(); it != v.end (); it++) { k -= it->second; if (k <= 0) return it->first; } return -1; } int sum(int l, int r, int ex, int mod) { IT itr = split(r + 1), itl = split(l); int res = 0; while (itl != itr) { res = (res + (itl->r - itl->l + 1) * quick_power(itl->v, ex, mod)) % mod; itl++; } return res; } void write(int x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10); putchar(x % 10 + '0'); } signed main() { n = read(), m = read(), seed = read(), vmax = read(); rep(i, 1, n) { a[i] = (rnd() % vmax) + 1; s.insert(node(i, i, a[i])); } s.insert(node(n + 1, n + 1, 0)); rep(i, 1, m) { int opt = (rnd() % 4) + 1; int l = (rnd() % n) + 1; int r = (rnd() % n) + 1; if (l > r) l ^= r ^= 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) { write(kth(l, r, x)); printf("\n"); } else { write(sum(l, r, x, y)); printf("\n"); } } return 0; }