2018 Multi-University Training Contest 5-G-Glad You Came

题目链接:HDU-6356-Glad You Came

(一)题面:

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

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≤1e5, 1≤m≤5⋅1e6, 0≤X,Y,Z<2^30.
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⋅1e7.

 

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

 

(二)题意:

有一个长度为n的序列,初始值全为0,然后给定m个操作,每个操作指定区间[L,R]和值v,然后将该区间中所有小于v的值替换成v。其中每次操作的L、R和v由一个给定的“随机”函数生成。求经过m次操作以后序列中各个<值与其下标的乘积>的异或值(看原题中表达式更清楚)。

 

(三)题解:

对于每次操作,我们都会将区间中小于v的值变为v,那么我们就维护一下区间的最小值,当区间的最小值小于v时,将该区间的最小值更新为v,然后就只是一个简单的线段树的区间维护最小值而已了,打个lazy即可。由于这里的数据随机给出,所以线段树实际上的效率还比较高。

 

(四)代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#define LL long long
#define UINT unsigned int
#define MOD (1<<30)
using namespace std;
const int maxn=1e5+10;
UINT F[maxn*150];
UINT X,Y,Z;
UINT FUNC(){
    X=X^(X<<11);X=X^(X>>4);
    X=X^(X<<5);X=X^(X>>14);
    UINT W=X^(Y^Z);
    X=Y;Y=Z;Z=W;
    return Z;
}
struct Tree{
    int l,r,lazy,_min;
    int mid(){return (l+r)>>1;}
}tree[maxn<<2];
void PushDown(int rt){
    if(tree[rt].lazy){
        if(tree[rt<<1]._min<tree[rt].lazy){
            tree[rt<<1].lazy=tree[rt].lazy;
            tree[rt<<1]._min=tree[rt].lazy;
        }
        if(tree[rt<<1|1]._min<tree[rt].lazy){
            tree[rt<<1|1].lazy=tree[rt].lazy;
            tree[rt<<1|1]._min=tree[rt].lazy;
        }
        tree[rt].lazy=0;
    }
}
void BuildTree(int rt,int l,int r){
    tree[rt].l=l;tree[rt].r=r;
    tree[rt].lazy=tree[rt]._min=0;
    if(l==r)return;
    int m=tree[rt].mid();
    BuildTree(rt<<1,l,m);
    BuildTree(rt<<1|1,m+1,r);
}
void UpdataTree(int rt,int l,int r,int v){
    if(l<=tree[rt].l&&tree[rt].r<=r){
        tree[rt].lazy=v;
        tree[rt]._min=v;
        return;
    }
    PushDown(rt);
    int m=tree[rt].mid();
    if(r<=m&&tree[rt<<1]._min<v)UpdataTree(rt<<1,l,r,v);
    else if(l>m&&tree[rt<<1|1]._min<v)UpdataTree(rt<<1|1,l,r,v);
    else if(r>m&&l<=m){
        if(tree[rt<<1]._min<v)UpdataTree(rt<<1,l,m,v);
        if(tree[rt<<1|1]._min<v)UpdataTree(rt<<1|1,m+1,r,v);
    }
    tree[rt]._min=min(tree[rt<<1]._min,tree[rt<<1|1]._min);
}
LL ans=0;
void QueryTree(int rt,int l,int r){
    if(l==r){
        ans^=(1ll*l*tree[rt]._min);
        return;
    }
    PushDown(rt);
    int m=tree[rt].mid();
    QueryTree(rt<<1,l,m);
    QueryTree(rt<<1|1,m+1,r);
}
int main(){
//    freopen("in.txt","r",stdin);
    int T,n,m;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%u%u%u",&n,&m,&X,&Y,&Z);
        for(int i=1;i<=3*m;i++)F[i]=FUNC();
        BuildTree(1,1,n);
        for(int i=1;i<=m;i++){
            int l=min(F[3*i-2]%n+1,F[3*i-1]%n+1);
            int r=max(F[3*i-2]%n+1,F[3*i-1]%n+1);
            int v=F[3*i]%MOD;
            if(tree[1]._min<v)UpdataTree(1,l,r,v);
        }
        QueryTree(1,1,n);
        printf("%lld\n",ans);ans=0;
    }
    return 0;
}

 

(五)总结:

水题啊水题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值