题意:
(a,b)
(
a
,
b
)
区间内的数 =
max((a,b),val)
m
a
x
(
(
a
,
b
)
,
v
a
l
)
,初始为0,最后只有一次查询.
分析:
线段树维护区间最小值,lazy进行区间操作,要有个减枝过程:就是减掉区间
(a,b)min>=val
(
a
,
b
)
m
i
n
>=
v
a
l
的状态.
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = a; i <= b; ++i)
typedef long long LL;
const int MAXN = 4e5 + 10;
LL lazy[MAXN], dp[MAXN];
unsigned int a[MAXN * 40];
unsigned int f(unsigned int &x, unsigned int &y, unsigned int &z){
x = x ^ (x << 11);
x = x ^ (x >> 4);
x = x ^ (x << 5);
x = x ^ (x >> 14);
unsigned int w = x ^ (y ^ z);
x = y;
y = z;
z = w;
return z;
}
inline void up(int rt) {
dp[rt] = min(dp[rt << 1], dp[rt << 1 | 1]);
}
inline void down(int rt) {
lazy[rt << 1] = max(lazy[rt << 1], lazy[rt]);
lazy[rt << 1 | 1] = max(lazy[rt << 1 | 1], lazy[rt]);
dp[rt << 1] = max(dp[rt << 1], lazy[rt]);
dp[rt << 1 | 1] = max(dp[rt << 1 | 1], lazy[rt]);
}
inline void update(int rt, int L, int R, int l ,int r, unsigned int val) {
if(dp[rt] >= val || lazy[rt] >= val) return ;//减枝
if(l <= L && R <= r) {
lazy[rt] = max(1ll * val, lazy[rt]);
dp[rt] = max(1ll * val, dp[rt]);
return ;
}
down(rt);
int mid = (L + R) >> 1;
if(l <= mid) update(rt << 1, L, mid, l, r, val);
if(r > mid) update(rt << 1 | 1, mid + 1, R, l, r, val);
up(rt);
}
inline LL query(int rt, int L, int R, int l, int r) {
if(L == R) {
return dp[rt] * 1ll * L;
}
down(rt); LL ans = 0;
int mid = (L + R) >> 1;
if(l <= mid) ans ^= query(rt << 1, L, mid, l, r);
if(r > mid) ans ^= query(rt << 1 | 1, mid + 1, R, l, r);
return ans;
}
int main() {
int T, n, m;
unsigned int x, y, z;
scanf("%d", &T);
while(T--) {
memset(dp, 0, sizeof(dp));
memset(lazy, 0, sizeof(lazy));
cin >> n >> m >> x >> y >> z;
rep(i, 1, 3 * m) a[i] = f(x, y, z);
rep(i, 1, m) {
int le = min(a[3 * i - 2] % n + 1, a[3 * i - 1] % n + 1);
int ri = max(a[3 * i - 2] % n + 1, a[3 * i - 1] % n + 1);
unsigned int v = a[3 * i] % (1 << 30);
update(1, 1, n, le, ri, v);
}
LL ans = query(1, 1, n, 1, n);
printf("%lld\n", ans);
}
return 0;
}