2018 Multi-University Training Contest 4-Glad You Came(hdu 6356)

一、思路

线段树维护一个区间最小值,然后对于每次操作,做区间更新即可。要注意的是,在更新的时候,记得剪枝:如果当前更新的值$v \le minv$(minv为当前线段树节点所管辖区间的最小值),直接返回。否则,TLE。运行时间1500+ms,比标程2800+ms快将近两倍。

二、代码

#include<bits/stdc++.h>
using namespace std;
#define min(x, y) (x < y ? x : y)
#define max(x, y) (x > y ? x : y)
#define MAXN 100100

unsigned X, Y, Z;
struct node {
    int mv, lazy;
} data[MAXN * 4];
int n, m;

inline void down(int rt) {
    if(data[rt].lazy) {
        int lch = rt << 1, rch = rt << 1 | 1;
        if(data[lch].lazy < data[rt].lazy)data[lch].lazy = data[rt].lazy;
        if(data[lch].mv < data[rt].lazy)data[lch].mv = data[rt].lazy;
        if(data[rch].lazy < data[rt].lazy)data[rch].lazy = data[rt].lazy;
        if(data[rch].mv < data[rt].lazy)data[rch].mv = data[rt].lazy;
        data[rt].lazy = 0;
    }
}

inline void update(int ul, int ur, int v, int rt = 1, int l = 1, int r = n) {
    if(l > ur || r < ul)return;
    if(v <= data[rt].mv)return;
    if(l >= ul && r <= ur) {
        if(data[rt].mv < v)data[rt].mv = v, data[rt].lazy = v;
        return;
    }
    down(rt);
    int mid = (l + r) >> 1;
    update(ul, ur, v, rt << 1, l, mid);
    update(ul, ur, v, rt << 1 | 1, mid + 1, r);
    data[rt].mv = min(data[rt << 1].mv, data[rt << 1 | 1].mv);
}

inline int query(int x, int rt = 1, int l = 1, int r = n) {
    if(l == r)return data[rt].mv;
    down(rt);
    int mid = (l + r) >> 1;
    if(x <= mid)return query(x, rt << 1, l, mid);
    else return query(x, rt << 1 | 1, mid + 1, r);
}

inline unsigned rng61() {
    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;
}



int main() {
//    freopen("1007.in", "r", stdin);
//    freopen("1007.out", "w", stdout);
    int T, mod = (1 << 30) - 1;
    scanf("%d", &T);
    for(int ca = 0; ca < T; ++ca) {
        scanf("%d%d%u%u%u", &n, &m, &X, &Y, &Z);
        memset(data, 0, sizeof(data[0]) * ((n << 2) + 5));
        for(int jj = 0; jj < m; ++jj) {
            unsigned f1 = rng61(), f2 = rng61();
            if(f1 >= n)f1 %= n;
            if(f2 >= n)f2 %= n;
            int ul = f1 + 1, ur = f2 + 1, v = rng61() & mod;
            if(ul > ur)swap(ul, ur);
            update(ul, ur, v);
        }
        long long ans = 0;
        for(int i = 1; i <= n; ++i)ans ^= 1LL * i * query(i);
        printf("%lld\n", ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/565261641-fzh/p/9436369.html
今日推荐