2018HDU多校五-G题 Glad You Game (线段树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356            
                         Glad You Game 
Steve has an integer array aa of length nn (1-based). He assigned all the elements as zero at the beginning. After that, he made mm operations, each of which is to update an interval of aa with some value. You need to figure out ni=1(iai)⨁i=1n(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,YX,Y and ZZ 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,YX,Y and ZZ after calling. 

Let the ii-th result value of calling the above function as fifi (i=1,2,,3m)(i=1,2,⋯,3m). The ii-th operation of Steve is to update ajaj as vivi if aj<viaj<vi (j=li,li+1,,ri)(j=li,li+1,⋯,ri), where 
⎧⎩⎨lirivi=min((f3i2modn)+1,(f3i1modn)+1)=max((f3i2modn)+1,(f3i1modn)+1)=f3imod230(i=1,2,,m).{li=min((f3i−2modn)+1,(f3i−1modn)+1)ri=max((f3i−2modn)+1,(f3i−1modn)+1)vi=f3imod230(i=1,2,⋯,m).

InputThe first line contains one integer TT, indicating the number of test cases. 
Each of the following TT lines describes a test case and contains five space-separated integers n,m,X,Yn,m,X,Y and ZZ. 
1T1001≤T≤100, 1n1051≤n≤105, 1m51061≤m≤5⋅106, 0X,Y,Z<2300≤X,Y,Z<230. 
It is guaranteed that the sum of nn in all the test cases does not exceed 106106 and the sum of mm in all the test cases does not exceed 51075⋅107.
OutputFor 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.

        
题意:给你一个生成L,R,V 的函数,让你对区间L~R的数,把小于v的数都变为v,最后求所有数的异或;
题解:我们利用线段树维护每一段区间的最大值,最小值,对于一段区间L~R,如果最大值都小于V,那么久更新整个区间,如果最小值都大于V,就不操作;最后暴力查找每个位置的数异或求值即可;
参考代码:
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long LL;
  4 const int maxn=1e5+10;
  5 int n,m,T;
  6 unsigned int X,Y,Z;
  7 
  8 struct Node{
  9     int l,r,maxnum,minnum,tag;
 10 } tree[maxn<<2];
 11 
 12 unsigned int functions()
 13 {
 14     X=X^(X<<11);
 15     X=X^(X>>4);
 16     X=X^(X<<5);
 17     X=X^(X>>14);
 18     unsigned int w=X^(Y^Z);
 19     X=Y; Y=Z; Z=w;
 20     return Z;
 21 }
 22 
 23 void build(int pos,int l,int r)
 24 {
 25     tree[pos].l=l,tree[pos].r=r,tree[pos].tag=-1;
 26     if(l==r) 
 27     {
 28         tree[pos].maxnum=0;
 29         tree[pos].minnum=0;
 30         return ;
 31     }
 32     int mid=(tree[pos].l+tree[pos].r)>>1;
 33     build(pos<<1,l,mid);
 34     build(pos<<1|1,mid+1,r);
 35     tree[pos].maxnum=max(tree[pos<<1].maxnum,tree[pos<<1|1].maxnum);
 36     tree[pos].minnum=min(tree[pos<<1].minnum,tree[pos<<1|1].minnum);
 37 }
 38 
 39 void pushup(int pos)
 40 {
 41     tree[pos].maxnum=max(tree[pos<<1].maxnum,tree[pos<<1|1].maxnum);
 42     tree[pos].minnum=min(tree[pos<<1].minnum,tree[pos<<1|1].minnum);
 43 }
 44 
 45 void pushdown(int pos)
 46 {
 47     tree[pos<<1].maxnum=max(tree[pos<<1].maxnum,tree[pos].tag);
 48     tree[pos<<1|1].maxnum=max(tree[pos<<1|1].maxnum,tree[pos].tag);
 49     tree[pos<<1].minnum=max(tree[pos<<1].minnum,tree[pos].tag);
 50     tree[pos<<1|1].minnum=max(tree[pos<<1|1].minnum,tree[pos].tag);
 51     tree[pos<<1].tag=max(tree[pos<<1].tag,tree[pos].tag);
 52     tree[pos<<1|1].tag=max(tree[pos<<1|1].tag,tree[pos].tag);
 53     tree[pos].tag=-1;
 54 }
 55 
 56 void update(int pos,int l,int r,int val)
 57 {
 58     if(tree[pos].l==tree[pos].r) 
 59     {
 60         tree[pos].maxnum=max(tree[pos].maxnum,val);
 61         tree[pos].minnum=max(tree[pos].minnum,val);
 62         return ;
 63     }
 64     if(tree[pos].l>=l&&tree[pos].r<=r) 
 65     {
 66         if(tree[pos].maxnum<=val)
 67         {
 68             tree[pos].maxnum=tree[pos].minnum=val;
 69             tree[pos].tag=max(tree[pos].tag,val);
 70             return ;
 71         }
 72     }
 73     if(tree[pos].minnum>=val) return ;
 74     
 75     if(tree[pos].tag!=-1) pushdown(pos);
 76     int mid=(tree[pos].l+tree[pos].r)>>1;
 77     if(r<=mid) update(pos<<1,l,r,val);
 78     else if(l>=mid+1) update(pos<<1|1,l,r,val);
 79     else update(pos<<1,l,mid,val),update(pos<<1|1,mid+1,r,val);
 80     pushup(pos);    
 81 }
 82 
 83 int query(int pos,int k)
 84 {
 85     if(tree[pos].l==tree[pos].r&&tree[pos].l==k) return tree[pos].maxnum;
 86     int mid=(tree[pos].l+tree[pos].r)>>1;
 87     if(tree[pos].tag!=-1) pushdown(pos);
 88     if(k<=mid) return query(pos<<1,k);
 89     else return query(pos<<1|1,k);
 90 }
 91 
 92 int main()
 93 {
 94     ios::sync_with_stdio(false);
 95     cin.tie(0);
 96     cin>>T;
 97     while(T--)
 98     {
 99         LL ans=0;
100         cin>>n>>m>>X>>Y>>Z;
101         build(1,1,n);
102         for(int i=1;i<=m;i++)
103         {
104             int l=functions()%n+1;
105             int r=functions()%n+1;
106             int v=functions()%(1<<30);
107             if(l>r) swap(l,r);
108             update(1,l,r,v);
109         }
110         for(int i=1;i<=n;i++) ans^=1ll*i*query(1,i);
111         cout<<ans<<endl;
112     }
113     
114     return 0;
115 }
View Code
原文地址:https://www.cnblogs.com/csushl/p/9482441.html