zoukankan      html  css  js  c++  java
  • 最大值

    1701:最大值

    时间限制: 1000 ms         内存限制: 262144 KB

    【题目描述】

    你需要在[0,2n)中选一个整数x,接着把x依次异或m个整数a1~am。

    在你选出x后,你的对手需要选择恰好一个时刻(刚选完数时、异或一些数后或是最后),将x变为(ceil(2*x/pow(2,n))+2*x)%pow(2,n)。

    你想使x最后尽量大,而你的对手会使x最后尽量小。

    你需要求出x最后的最大值,以及得到最大值的初值数量。

    【输入】

    第一行两个整数n,m。

    第二行m个整数a1~am。

    【输出】

    第一行输出一个整数,表示x最后的最大值。

    第二行输出一个整数,表示得到最大值的初值数量。

    【输入样例】

    2 3
    1 2 3

    【输出样例】

    1
    2

    【提示】

    【样例解释】

    x=0时得到0,x=1时得到1,x=2 时得到1,x=3时得到0。

    【数据规模】

    对于20%的数据,n≤10,m≤100。

    对于40%的数据,n≤10,m≤1000。

    对于另外20%的数据,n≤30,m≤10。

    对于100%的数据, n≤30,m≤100000,0≤ai<2n。

    【题解】

    首先分析他对手的操作。发现它即为将x的第一位移到最后一位,前面的位数依次向前左移一位,即为循环左移1位。

    发现将异或路径上所有数全部循环左移一位后的异或前缀和异或X等于原始异或前缀和异或X再循环左移一位。

    可预处理出对手所有可以操作出的给X异或的值。

    将他们按31位从高到低加入01trie中。

    遍历trie,如果这一位只有左儿子或右儿子则可将当前答案这一位赋为1,否则为0,在遍历左右儿子。

    代码如下:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e5+5;
    int qi[N],hou[N],n,m,a[N],nn=1,zong[N],cnt,ans1,ans2;
    struct trie
    {
        int er[2];
    }sh[N*30];
    inline int read()
    {
        char c=getchar();
        int x=0,f=1;
        while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
        while(isdigit(c)) {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
        return x*f;
    }
    inline int suan(int x)
    {
        return ((2*x)/nn+2*x)%nn;
    }
    inline void insert(int x)
    {
        int now=0;
        for(int i=n-1;i>=0;i--)
        {
            int pu=(x>>i)&1;
            if(!sh[now].er[pu]) sh[now].er[pu]=++cnt;
            now=sh[now].er[pu];
        }
    }
    inline void solve(int now,int daan,int ge)
    {
        if(ge==-1)
        {
            if(daan>ans1) ans1=daan,ans2=1;
            else if(daan==ans1) ans2++;
            return;
        }
        if(!sh[now].er[0]) solve(sh[now].er[1],daan|(1<<ge),ge-1);
        else if(!sh[now].er[1]) solve(sh[now].er[0],daan|(1<<ge),ge-1);
        else
        {
            solve(sh[now].er[0],daan,ge-1);
            solve(sh[now].er[1],daan,ge-1);
        }
    }
    signed main()
    {
        n=read();m=read();
        for(int i=1;i<=n;i++) nn*=2; 
        for(int i=1;i<=m;i++) a[i]=read();
        for(int i=1;i<=m;i++)
        {
            qi[i]=qi[i-1]^suan(a[i]);
        }
        for(int i=m;i>=1;i--) hou[i]=hou[i+1]^a[i];
        for(int i=0;i<=m;i++) zong[i]=qi[i]^hou[i+1];
        for(int i=0;i<=m;i++) insert(zong[i]);
        solve(0,0,n-1);
        cout<<ans1<<"
    "<<ans2;
    }
  • 相关阅读:
    jenkins系列---【linux安装nodejs】
    jenkins系列---【jenkins+gitlab+springCloud实现CI和CD】
    jenkins系列---【jenkins创建账号、分配角色】
    idea系列---【启动的时候报:Error running FinanceApplication. Command line is too long. Shorten the command line via JAR manifest or via a classpath file and rerun】
    ubuntu apt-get install xxx时一直报错E: Unable to locate package xxxxxxx
    mysql binlog 使用
    python项目导出所需要的依赖库
    mysql 导入sql文件时编码报错
    mysqldumps 远程备份
    pymongo的基本使用
  • 原文地址:https://www.cnblogs.com/betablewaloot/p/12146726.html
Copyright © 2011-2022 走看看