CF896C Willem, Chtholly and Seniorious 珂朵莉树
不管毒瘤出题人卡不卡珂朵莉树我都永远喜欢珂朵莉。
就当存个好看的板子,放上有注释的代码。
总之记住看见数据随机想想珂朵莉树总没错。
不要问我为什么代码长得和洛谷第一篇题解那么像,你以为我是从哪里学的?
#include <cstdio>
#include <set>
#include <algorithm>
#include <vector>
#define R register
#define I inline
#define L long long
#define IT set <node> :: iterator//敢用auto?
using namespace std;
const int N = 100003, yyb = 1e9 + 7;//yyb还是要膜的
L seed, vmax;
I L random() {
L x = seed;
seed = (seed * 7 + 13) % yyb;
return x;
}//数据生成器,等于告诉你这是随机数据,可以珂朵莉树艹过去
L power(L a, L b, L mod) {
L r = 1;
for (a = a % mod; b; a = a * a % mod, b = b >> 1)//a = a % mod,你可以不加试试
if (b & 1)
r = r * a % mod;
return r;
}
struct node {
int l, r;
mutable L v;
node(int _l, int _r = -1, L _v = 0) : l(_l), r(_r), v(_v) {}
int operator < (const node &y) const { return l < y.l; }//存进set
};
set <node> c;
I IT split(int x) {//一个区间拆成两个
IT i = c.lower_bound(node(x));//找到
if (i != c.end() && i->l == x)//不用拆
return i;
--i;//要拆的在前面一个区间
R int l = i->l, r = i->r;
L v = i->v;
c.erase(i), c.insert(node(l, x - 1, v));//拆了
return c.insert(node(x, r, v)).first;//插入,顺便返回迭代器
}
I void modify(int l, int r, L v) {//区间加,大暴力
IT il = split(l), ir = split(r + 1);
for (; il != ir; ++il)
il->v += v;
}
I void assign(int l, int r, L v) {//推平,大暴力,复杂度的保证
IT il = split(l), ir = split(r + 1);
c.erase(il, ir), c.insert(node(l, r, v));
}
I void kth(int l, int r, int k) {//第K大,大暴力
vector <pair <L, int> > vec;//暴力开啊
vec.clear();
IT il = split(l), ir = split(r + 1);
for (; il != ir; ++il)
vec.push_back(make_pair(il->v, il->r - il->l + 1));
sort(vec.begin(), vec.end());//全丢进来排序
for (R int i = 0, m = vec.size(); i < m; ++i) {//暴力啊
k -= vec[i].second;
if (k <= 0) {
printf("%I64d\n", vec[i].first);
return ;
}
}
printf("-1\n");
}
I void query(int l, int r, int ex, int mod) {//查询ex次方,大暴力
IT il = split(l), ir = split(r + 1);
L o = 0;
for (; il != ir; ++il)
o = (o + power(il->v, ex, mod) * (il->r - il->l + 1)) % mod;
printf("%I64d\n", o);
}
int main() {
R int n, m, i, l, r, o, x, y;
scanf("%d%d%I64d%I64d", &n, &m, &seed, &vmax);
for (i = 1; i <= n; ++i)
x = random() % vmax + 1, c.insert(node(i, i, x));
c.insert(node(n + 1, n + 1, 0));
for (i = 1; i <= m; ++i) {
o = random() % 4 + 1, l = random() % n + 1, r = random() % n + 1;
if (r < l)
swap(l, r);
if (o == 3)
x = random() % (r - l + 1) + 1;
else
x = random() % vmax + 1;
if (o == 4)
y = random() % vmax + 1;
switch (o) {//switch真长
case 1: {
modify(l, r, x);
break;
}
case 2: {
assign(l, r, x);
break;
}
case 3: {
kth(l, r, x);
break;
}
case 4: {
query(l, r, x, y);
break;
}
}
}
return 0;
}