Problem meaning: n numbers, through an algorithm and generators X,Y,Z to generate m group updates. Each time, the number less than V in [l,r][l,r] is updated to v.
The values of (1 a[1]) (2 a[2] (n a[n])(1 a[1]) (2 a[2] (n a[n]) after m updates are calculated. Among them,
The main contradiction in the topic is to update the values in the interval quickly. Referring to the code of dls, it can be implemented skillfully through st table.
Since the updating operation takes max as an interval, it is entirely possible to divide [l,r][l,r] into [l,k1][l,k1] and [k2,r][k2,r] and K1 > K2 K1 > k2, and then update in these two intervals. Contact the initialization and query process of the st table. You can reverse the initialization and query process.
For general st table query operations, if you want to query the value of [l, r], you usually query [l,l+2d 1][l,l+2d 1] and [r 2d+1,r][r 2d+1,r](d=logr l+12)(d=log2r l+1) and then merge them. It can be seen here as a marking process.
After m updates, each large subinterval is updated to its left and right subintervals until the leaf nodes. Then just do it again.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
int T, n, m, st[25][maxn], Log[maxn];
unsigned X, Y, Z;
unsigned RNG61() {
unsigned W;
X = X ^ (X << 11);
X = X ^ (X >> 4);
X = X ^ (X << 5);
X = X ^ (X >> 14);
W = X ^ (Y ^ Z);
X = Y;
Y = Z;
Z = W;
return Z;
}
void update(int l, int r, int v) {
int d = Log[r - l + 1];
st[d][l] = max(st[d][l], v);
st[d][r - (1 << d) + 1] = max(st[d][r - (1 << d) + 1], v);
}
int main() {
#ifdef __APPLE__
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
Log[2] = 1;
for (int i = 3; i <= 100003; i++) {
Log[i] = Log[i >> 1] + 1;
// cout << Log[i] << endl;
}
cin >> T;
while (T--) {
cin >> n >> m >> X >> Y >> Z;
for (int j = 0; j < 20; j++) {
for (int i = 1; i <= n; i++) {
st[j][i] = 0;
}
}
while (m--) {
int x = RNG61() % n + 1, y = RNG61() % n + 1, z = RNG61() % (1 << 30);
update(min(x, y), max(x, y), z);
// cout << x << " " << y << " " << z << endl;
}
for (int j = 19; j >= 1; j--) {
for (int i = 1; i + (1 << j) - 1 <= n; i++) {
st[j - 1][i] = max(st[j - 1][i], st[j][i]);
st[j - 1][i + (1 << j - 1)] = max(st[j - 1][i + (1 << j - 1)], st[j][i]);
}
}
ll ans = 0;
for (int i = 1; i <= n; i++) {
// cout << st[0][i] << endl;
ans ^= 1ll * i * (ll)st[0][i];
}
cout << ans << endl;
}
}