Glad You Came (HDU 多校)(线段树)

  • 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356
  • 题意:求n个数的 ( i×a[i] )异或和。这n个数初始值都为0,有m次操作,每次操作给出三个整数:l, r, v。表示将(l<=i <=r)的a[i] 变为max(a[i], v)。为了避免大量的输入数据,题目给你一个生成函数,和三个unsigned int 类型的参数。通过题目给的算法算出每次的l,r,v。
  • 算法:线段树

#include <bits/stdc++.h>
#define pi acos(-1)
#define fastcin ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;       // 不能加负号!!!
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;//4e18 ~= 2^62
const int maxn =100000 + 10;
const LL mod = (1<<30);

unsigned int  RNG61(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;
}

LL maxx[maxn<<2];
LL lazy[maxn<<2];
LL a[maxn];

void PushUp(int rt)
{
    maxx[rt] = max(maxx[rt<<1], maxx[rt<<1|1]);
}
void PushDown(int rt, int ln, int rn)
{
    if(lazy[rt]){
        lazy[rt<<1] = lazy[rt];
        lazy[rt<<1|1] = lazy[rt];
        maxx[rt<<1] = lazy[rt];
        maxx[rt<<1|1] = lazy[rt];

        if(ln == rn){
            a[ln] = lazy[rt];
        }
        lazy[rt] = 0;
    }

}


//区间更新,假设A[L,R]+=C
void update(int L, int R, int v, int l, int r, int rt)
{
    //cout<<l<<"____"<<r<<"....."<<rt<<endl;
    if(L<=l && r<=R && max(maxx[rt],lazy[rt])<=v){
        lazy[rt] = v;
        maxx[rt] = v;
        for(int i = l; i<=r ; i++){
            a[i] = v;
        }

        return ;
    }
    if(l == r){
        return ;
    }

    int mid = (l+r)>>1;
    PushDown(rt, l, r);
    if(L <= mid) update(L, R, v, l, mid, rt<<1);
    if(R >  mid) update(L, R, v, mid+1, r, rt<<1|1);
    PushUp(rt);
}

int main()
{

    int T; scanf("%d", &T);

    while(T--){
        int n, m, l, r, v;
        memset(lazy,0,sizeof(lazy));
        memset(maxx,0,sizeof(maxx));
        memset(a,0,sizeof(a));

        unsigned int X, Y, Z;
        scanf("%d%d%u%u%u", &n, &m, &X, &Y, &Z);
        unsigned int t1, t2, t3;
        for(int i=0; i<m; i++){
            t1 = RNG61(X, Y, Z);
            t2 = RNG61(X, Y, Z);
            t3 = RNG61(X, Y, Z);
            l = min((t1%n)+1, (t2%n)+1);
            r = max((t1%n)+1, (t2%n)+1);
            v = t3 % mod;
            //cout<<l<<"...."<<r<<"....."<<v<<endl;
            update(l, r, v, 1, n, 1);
        }
        LL ans = 0;
        for(int i=1; i<=n; i++){
            ans ^= a[i]*i;
        }
        printf("%lld\n", ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37352710/article/details/81476379
今日推荐