zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    C++中简单使用HPSocket time
    error: cannot lock ref ‘refs/remotes/origin/[branch]’

    linux 挂载移动硬盘
    音频读写
    无法连接NVIDIA驱动
    nodejs
    read the docs
    用 scp 在 linux 之间传输文件
    配置 frp 常用功能
  • 原文地址:https://www.cnblogs.com/csushl/p/9482441.html
Copyright © 2011-2022 走看看