https://ac.nowcoder.com/acm/contest/58568/J
随机数据 , 区间覆盖 , 区间X次方和
很明显,珂朵莉
用DFS序把子树转成区间就好了
#include <bits/stdc++.h>
#define endl "\n"
#define ls p << 1
#define rs p << 1 | 1
#define int long long
#define pb push_back
#define mem(a, b) memset(a, b, sizeof(a))
#define For(i, a, b) for (int i = (a); i <= (b); i++)
#define io \
std::ios::sync_with_stdio(false); \
std::cin.tie(0); \
std::cout.tie(0)
using namespace std;
typedef pair<int, int> PII;
typedef unsigned long long u64;
mt19937_64 mrand(random_device{}());
template <typename T>
inline void read(T& x) {
int f = 1;
x = 0;
char c = getchar();
while (!isdigit(c)) {
if (c == '-')
f = -1;
c = getchar();
}
while (isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
}
// long long long
// Êý×鿪¹» N+10
// ÓÐÏòͼ or ÎÞÏòͼ
// ¶à×éÊý¾Ý,³õʼ»¯
// LLLLLLLLLLLLL
const int N = 1e6 + 10;
const int inf = 8e18;
const int mod = 1e9 + 7;
struct my {
int l, r;
mutable int v;
my(int l, int r = 0, int v = 0)
: l(l), r(r), v(v) {
}
bool operator<(const my& a) const {
return l < a.l;
}
};
int n, m, seed, vmax, a[N];
int le[N], re[N];
int h[N], e[N], ne[N];
int idx, back[N], cnt;
set<my> s;
set<my>::iterator split(int pos) {
set<my>::iterator it = s.lower_bound(my(pos));
if (it != s.end() && it->l == pos) {
return it;
}
it--;
if (it->r < pos)
return s.end();
int l = it->l, r = it->r, v = it->v;
s.erase(it);
s.insert(my(l, pos - 1, v));
return s.insert(my(pos, r, v)).first;
}
void assign(int l, int r, int x) {
set<my>::iterator itr = split(r + 1), itl = split(l);
s.erase(itl, itr);
s.insert(my(l, r, x));
}
int qmi(int a, int b, int p) {
int res = 1;
a = a % p;
while (b) {
if (b & 1) {
res = res * a % p;
}
a = a * a % p;
b = b >> 1;
}
return res;
}
int calP(int l, int r, int x, int y) {
set<my>::iterator itr = split(r + 1), itl = split(l);
int ans = 0;
for (auto i = itl; i != itr; ++i) {
ans = (ans + qmi(i->v, x, y) * (i->r - i->l + 1) % y) % y;
}
return ans;
}
int rnd() {
int res = seed;
seed = (seed * 7 + 13) % mod;
return res;
}
void add(int a, int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void dfs(int x, int fa) {
++cnt;
le[x] = cnt;
back[cnt] = x;
for (int i = h[x]; i != -1; i = ne[i]) {
int j = e[i];
if (j == fa)
continue;
dfs(j, x);
}
re[x] = cnt;
}
signed main() {
io;
mem(h, -1);
cin >> n >> m >> seed >> vmax;
For(i, 1, n) {
a[i] = (rnd() % vmax) + 1;
// s.insert(my(i, i, a[i]));
}
For(i, 2, n) {
int x = (rnd() % (i - 1)) + 1;
add(i, x);
add(x, i);
}
dfs(1, 1);
For(i, 1, n) {
int x = le[i];
s.insert(my(x, x, a[i]));
}
For(i, 1, m) {
int op, l, r, x, y;
op = (rnd() % 2) + 1;
l = (rnd() % n) + 1;
x = (rnd() % vmax) + 1;
int a, b;
a = le[l];
b = re[l];
if (op == 1) {
assign(a, b, x);
} else {
cout << calP(a, b, x, mod) << endl;
}
}
return 0;
}