• hdu6356 Glad You Came 杭电多校第五场 RMQ ST表(模板)


    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(iai) 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
    ⎧⎩⎨⎪⎪lirivi=min((f3i2modn)+1,(f3i1modn)+1)=max((f3i2modn)+1,(f3i1modn)+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.
    1T1001n1051m51060X,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 5107.
     
    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;
    }
    

      

      

     
    彼时当年少,莫负好时光。
  • 相关阅读:
    [HAOI2008] 硬币购物
    [HNOI2002] Kathy 函数
    [SCOI2009] windy数
    圆方树总结
    ABOUT ME && 友链
    逝念偶拾
    文化课日常
    记一些欢愉
    浅谈
    洛谷 4823 [TJOI2013]拯救小矮人
  • 原文地址:https://www.cnblogs.com/l609929321/p/9437505.html
Copyright © 2020-2023  润新知