zoukankan      html  css  js  c++  java
  • Operation

     Operation

    时间限制: 5 Sec  内存限制: 256 MB

    题目描述

    There is an integer sequence a of length n and there are two kinds of operations:
    0 l r: select some numbers from al...ar so that their xor sum is maximum, and print the maximum value.
    1 x: append x to the end of the sequence and let n=n+1.

    输入

    There are multiple test cases. The first line of input contains an integer T(T≤10), indicating the number of test cases.
    For each test case: 
    The first line contains two integers n,m(1≤n≤5×105,1≤m≤5×105), the number of integers initially in the sequence and the number of operations.
    The second line contains n integers a1,a2,...,an(0≤ai<230), denoting the initial sequence.
    Each of the next m lines contains one of the operations given above.
    It's guaranteed that ∑n≤106,∑m≤106,0≤x<230.
    And operations will be encrypted. You need to decode the operations as follows, where lastans denotes the answer to the last type 0 operation and is initially zero: 
    For every type 0 operation, let l=(l xor lastans)mod n + 1, r=(r xor lastans)mod n + 1, and then swap(l, r) if l>r.
    For every type 1 operation, let x=x xor lastans.

    输出

    For each type 0 operation, please output the maximum xor sum in a single line.

    样例输入

    1
    3 3
    0 1 2
    0 1 1
    1 3
    0 3 4
    

    样例输出

    1
    3

    题意:一个序列,两种操作:询问区间异或最大值(可选择区间内任意数异或),在区间末尾加一个数。
    思路:首先大思路是用线性基求区间异或最大值,然后考虑怎么求任一区间的异或最大值。考虑贪心,先构造出一个前缀线性基(即第i个线性基代表1-i这些数的基底),然后每次将数加进线性基的时候,贪心的保留位置靠后的数,这样保证每个数只会和比自己位置大的数异或。然后查询区间[L,R]的时候,在第R个线性基里面查询位置大于等于L的基底,并统计答案。
    线性基参考博客https://blog.csdn.net/qaq__qaq/article/details/53812883
    区间最大异或和参考博客https://www.cnblogs.com/hua-dong/p/10266216.html
    #include<bits/stdc++.h>
    using namespace std;
    
    
    struct L_B
    {
        int d[30+1],p[30+1];
        L_B()
        {
            memset(d,0,sizeof(d));
            memset(p,0,sizeof(p));
        }
    
        void operator = (const L_B & s)
        {
            for(int i=0;i<31;i++)d[i]=s.d[i],p[i]=s.p[i];
        }
    
        bool insert(int val,int pos)
        {
            for (int i=30;i>=0;i--)
                if (val&(1LL<<i))
                {
                    if (!d[i])
                    {
                        d[i]=val;
                        p[i]=pos;
                        break;
                    }
    
                    if(p[i]<pos)
                    {
                        int now;
    
                        now=p[i];
                        p[i]=pos;
                        pos=now;
    
                        now=d[i];
                        d[i]=val;
                        val=now;
                       // swap((long long)pos,p[i]);
                        //swap((long long)val,d[i]);
                    }
    
                    val^=d[i];
                }
            return val>0;
        }
        int query_max(int l)
        {
            int ret=0;
            for (int i=30;i>=0;i--)
                if (p[i]>=l&&(ret^d[i])>ret)
                    ret^=d[i];
            return ret;
        }
    };
    
    
    L_B pre[1000050];
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            int ans=0;
            scanf("%d %d",&n,&m);
            for(int i=1;i<=n;i++)
            {
                int a;
                scanf("%d",&a);
                pre[i]=pre[i-1];
                pre[i].insert(a,i);
            }
    
            while(m--)
            {
                int op;
                scanf("%d",&op);
    
                if(op==1)
                {
                    int x;
                    scanf("%d",&x);
                    x=x^ans;
                    n++;
                    pre[n]=pre[n-1];
                    pre[n].insert(x,n);
                }
                else
                {
                    int l,r;
                    scanf("%d %d",&l,&r);
    
                    l=(l^ans)%n+1;
                    r=(r^ans)%n+1;
                    if(l>r)swap(l,r);
                    ans=pre[r].query_max(l);
                    printf("%d
    ",ans);
                }
            }
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    C# 字典 Dictionary 转 JSON 格式遍历
    jquery-easyui-tree异步树
    android 开发环境搭建
    解决android sdk 无法更新
    043——VUE中组件之使用.sync修饰符与computed计算属性实现购物车原理
    laravel中数据库迁移的使用:
    002PHP文件处理——文件处理 is_dir mkdir getcwd chdir rmdir
    001PHP文件处理——文件处理disk_total_space disk_free_space basename dirname file_exists filetype
    042——VUE中组件之子组件使用$on与$emit事件触发父组件实现购物车功能
    041——VUE中组件之pros数据的多种验证机制实例详解
  • 原文地址:https://www.cnblogs.com/tian-luo/p/11236545.html
Copyright © 2011-2022 走看看