[2018 Multi-University Training Contest 5] HDU 6356 Glad You Came )

Keywords: PHP

Title Link

Glad You Came

The main idea of the topic

T group data.
Each group is given an array of length nn, which is initially a l l 0 and has mm operations. Each operation will update V of a < v a < V in interval [l,r][l,r].
Finally, ni=1(i * ai) i=1n(i * ai)
The input data is generated by the way given by the title.

Data range

1≤T≤1001≤T≤100
1≤n≤1051≤n≤105
1≤m≤5×1061≤m≤5×106

Solving problems

This question was not written out in the competition. We can see that the data range must be the card segment tree. The complexity of the line segment tree is m_log(n)m_log(n) plus T group. Obviously, TLE did not think of the positive solution at last.
After the game, I looked at the problem, and it was so clear that I could do it. The complexity dropped to n log(n)n log(n).

For each interval [l,r][l,r], it can be converted to the length of the power of two segments.
Let d=[log2(r_1+1)]d=[log2(r_1+1)], then [l,r][l,r] can be split into [l,l+2d_1][l,l+2d_1] and [r_2d+1,r][r_2d+1,r], which guarantee complete coverage. That's the idea of RMQ.

In this way, there are at most log(n)log(n) line segments, from large to small enumeration, each line segment can be converted into two equal parts of the line segment, for exactly the same line segment, maintain the maximum value. So the line length of 1 is over.
Save it in an array, then Line(i,d)Line(i,d) represents the maximum carrying value of a line segment as long as 2d2d starting from I I.
Every time, it can be transferred to the uuuuuuuuuuu

Line(i,d−1)=max(Line(i,d−1),Line(i,d))Line(i+2d−1,d−1)=max(Line(i+2d−1,d−1),Line(i,d))Line(i,d−1)=max(Line(i,d−1),Line(i,d))Line(i+2d−1,d−1)=max(Line(i+2d−1,d−1),Line(i,d))

Finally, the answer can be calculated according to the requirements of the title.

Also, the way the title gives you data generation is a bit pitfalls, very slow.
In fact, we can compute three values at a time without calculating the ff array. No need to save it. At the same time, the number of modular NNs can be reduced.

AC code

/********************************************
 *Author*        :ZZZZone
 *Created Time*  : 18/620:26:08 2018
 * Ended  Time*  : 18/6 20:52:16 2018
*********************************************/

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <stack>
using namespace std;
#define debug(x) std::cerr << #x << " = " << (x) << std::endl
typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;

inline void OPEN(string s){
    freopen((s + ".in").c_str(), "r", stdin);
    freopen((s + ".out").c_str(), "w", stdout);
}

const int MAXN = 1e5;
const int MAXV = 5e6;
const int INF = 1 << 30;

unsigned X, Y, Z;
int n,m;

int Log2[MAXN+5];
int pow2[30];
LL Line[MAXN+5][35];

unsigned getnum(){
    X = X ^ (X << 11);
    X = X ^ (X >> 4);
    X = X ^ (X << 5);
    X = X ^ (X >> 14);
    unsigned W = X ^ (Y ^ Z);
    X = Y;
    Y = Z;
    Z = W;
    return Z;
}

void Init(){
    scanf("%d %d", &n, &m);
    scanf("%u %u %u", &X, &Y, &Z);
    for(int i = 1; i <= m; i++){
        int p = getnum() % n + 1, q = getnum() % n + 1;
        int l = min(p, q);
        int r = max(p, q);
        LL v = getnum() % INF;
        int d = Log2[r-l+1];
        Line[l][d] = max(Line[l][d], (LL)v);
        Line[r-pow2[d] + 1][d] = max(Line[r-pow2[d] + 1][d], (LL)v);
    }
}

void Solve(){
    for(int d = 30; d >= 1; d--){
        for(int i = 1; i +pow2[d] <= n+1; i++){
            Line[i][d-1] = max(Line[i][d-1], Line[i][d]);
            Line[i+pow2[d-1]][d-1] = max(Line[i+pow2[d-1]][d-1], Line[i][d]);
            Line[i][d] = 0LL;
        }
    }
    LL ans = 0LL;
    for(int i = 1; i <= n; i++){
        ans = ans ^ ((LL)i * Line[i][0]);
        Line[i][0] = 0LL;
    }
    printf("%lld\n", ans);
}

int main()
{
    Log2[0] = -1;
    pow2[0] = 1;
    for(int i = 1; i <= 30; i++) pow2[i] = pow2[i-1] * 2;
    for(int i = 1; i <= MAXN; i++) Log2[i] = Log2[i >> 1] + 1;
    int T; scanf("%d", &T);
    while(T--){
        Init();
        Solve();
    }
    return 0;
}

Posted by lixid on Tue, 25 Dec 2018 08:33:06 -0800