Glad You Came
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1489 Accepted Submission(s): 629
Problem Description
Steve has an integer array a of length n (1-based). He assigned all the elements as zero at the beginning. After that, he made m operations, each of which is to update an interval of a with some value. You need to figure out ⨁ni=1(i⋅ai) after all his operations are finished, where ⨁ means the bitwise exclusive-OR operator.
In order to avoid huge input data, these operations are encrypted through some particular approach.
There are three unsigned 32-bit integers X,Y and Z which have initial values given by the input. A random number generator function is described as following, where ∧ means the bitwise exclusive-OR operator, << means the bitwise left shift operator and >> means the bitwise right shift operator. Note that function would change the values of X,Y and Z after calling.
Let the i-th result value of calling the above function as fi (i=1,2,⋯,3m). The i-th operation of Steve is to update aj as vi if aj<vi (j=li,li+1,⋯,ri), where
In order to avoid huge input data, these operations are encrypted through some particular approach.
There are three unsigned 32-bit integers X,Y and Z which have initial values given by the input. A random number generator function is described as following, where ∧ means the bitwise exclusive-OR operator, << means the bitwise left shift operator and >> means the bitwise right shift operator. Note that function would change the values of X,Y and Z after calling.
Let the i-th result value of calling the above function as fi (i=1,2,⋯,3m). The i-th operation of Steve is to update aj as vi if aj<vi (j=li,li+1,⋯,ri), where
⎧⎩⎨⎪⎪lirivi=min((f3i−2modn)+1,(f3i−1modn)+1)=max((f3i−2modn)+1,(f3i−1modn)+1)=f3imod230(i=1,2,⋯,m).
Input
The first line contains one integer T, indicating the number of test cases.
Each of the following T lines describes a test case and contains five space-separated integers n,m,X,Y and Z.
1≤T≤100, 1≤n≤105, 1≤m≤5⋅106, 0≤X,Y,Z<230.
It is guaranteed that the sum of n in all the test cases does not exceed 106 and the sum of m in all the test cases does not exceed 5⋅107.
Each of the following T lines describes a test case and contains five space-separated integers n,m,X,Y and Z.
1≤T≤100, 1≤n≤105, 1≤m≤5⋅106, 0≤X,Y,Z<230.
It is guaranteed that the sum of n in all the test cases does not exceed 106 and the sum of m in all the test cases does not exceed 5⋅107.
Output
For each test case, output the answer in one line.
Sample Input
4
1 10 100 1000 10000
10 100 1000 10000 100000
100 1000 10000 100000 1000000
1000 10000 100000 1000000 10000000
Sample Output
1031463378
1446334207
351511856
47320301347
Hint
In the first sample, a = [1031463378] after all the operations.
In the second sample, a = [1036205629, 1064909195, 1044643689, 1062944339, 1062944339, 1062944339, 1062944339, 1057472915, 1057472915, 1030626924] after all the operations.
Source
首先用ST表维护区间最大值,st[i][j]维护的是i以后2^j个数的最大值
然后反向求一遍ST表可以求出每个数的最大值,此时st[i][0]就是每个数的最大值
再按照题目意思求每个值与其位置的乘积再异或一遍
贴一份讲解RMQ-ST表的博客:https://www.cnblogs.com/l609929321/p/9439145.html
AC代码:
#include <map> #include <set> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <vector> #include <string> #include <bitset> #include <cstring> #include <iomanip> #include <iostream> #include <algorithm> #define ls (r<<1) #define rs (r<<1|1) #define debug(a) cout << #a << " " << a << endl using namespace std; typedef long long ll; const ll maxn = 1e5+10; const ll mod = 998244353; const double pi = acos(-1.0); const double eps = 1e-8; unsigned x, y, z; unsigned rng() { x ^= x << 11; x ^= x >> 4; x ^= x << 5; x ^= x >> 14; unsigned w = x^(y^z); x = y; y = z; z = w; return z; } ll n, m, a[maxn], st[maxn][20], Log[maxn]; void update( ll le, ll ri, ll z ) { //维护(le,ri)区间最大值 ll k = Log[ri-le+1]; st[le][k] = max(st[le][k],z); st[ri-(1<<k)+1][k] = max(st[ri-(1<<k)+1][k],z); } int main() { ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); Log[2] = 1; for( ll i = 3; i < maxn; i ++ ) { //预处理区间所有log2()的值,节省时间 Log[i] = Log[i>>1]+1; } ll T; cin >> T; while( T -- ) { cin >> n >> m >> x >> y >> z; for( ll i = 1; i <= n; i ++ ) { //n最大的情况下,log2(maxn) = 16 for( ll j = 0; j < 18; j ++ ) { st[i][j] = 0; } } for( ll i = 1; i <= m; i ++ ) { ll x = rng()%n+1, y = rng()%n+1, z = rng()%(1<<30); update(min(x,y),max(x,y),z); } for( ll j = 17; j; j -- ) { //反向一遍st求出每一个数的最大值 for( ll i = 1; i+(1<<j)-1 <= n; i ++ ) { st[i][j-1] = max(st[i][j-1],st[i][j]); st[i+(1<<(j-1))][j-1] = max(st[i+(1<<(j-1))][j-1],st[i][j]); } } ll ans = 0; for( ll i = 1; i <= n; i ++ ) { ans = ans^(i*st[i][0]); } cout << ans << endl; } return 0; }