最大值
Posted betablewaloot
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最大值相关的知识,希望对你有一定的参考价值。
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; }
以上是关于最大值的主要内容,如果未能解决你的问题,请参考以下文章
[搬运] 将 Visual Studio 的代码片段导出到 VS Code
pandas GroupBy上的方法apply:一般性的“拆分-应用-合并”
NC41 最长无重复子数组/NC133链表的奇偶重排/NC116把数字翻译成字符串/NC135 股票交易的最大收益/NC126换钱的最少货币数/NC45实现二叉树先序,中序和后序遍历(递归)(代码片段