10月10日|9日考试
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10月10日|9日考试相关的知识,希望对你有一定的参考价值。
big
【题目描述】
你需要在[0,2^n)中选一个整数 x,接着把 x 依次异或 m 个整数
a1~am。
在你选出 x 后,你的对手需要选择恰好一个时刻(刚选完数时、
2x
异或一些数后或是最后)
,将 x 变为(⌊ n ⌋ + 2x) mod 2 n 。
2
你想使 x 最后尽量大,而你的对手会使 x 最后尽量小。
你需要求出 x 最后的最大值,以及得到最大值的初值数量。
【输入数据】
第一行两个整数 n,m。第二行 m 个整数 a1~am
【输出数据】
第一行输出一个整数,表示 x 最后的最大值。
第二行输出一个整数,表示得到最大值的初值数量。
第一个数正确得 6 分,两个数都正确再得 4 分。
【样例输入】
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<2^n。
题解:
看到2^n次方,首先想到2进制分解+tire树,然后考场上还发现了一个规律,(⌊ n ⌋ + 2x) mod 2^n就是将二进制位向前移动一位,然后超过2^n的向0位补齐,但想到这就不会了,我以为要tire树上写一个很难的dp,没想到一个转化。
我们枚举一个断点x,当然我们暴力做是异或两个数,但是我们可以把前x个数,每个数都按照上面所讲的向前移位,因为位运算不会相互影响,那么先异或这前x个数之后进行转化,和异或这转化后的前x个数是一样的,所以我们用转化过的前x个数,异或后面的m-x个数就得到我们正真想异或的数。因为有m个断点,所以我们就有m个数。
把m个树构在trie树上,那么考虑遍历这棵tire,剩下的就是简单贪心了,如果当前节点有两个儿子,那么对手一定会让你得不到这一位的1,如果只有一个,那么你就选和这个儿子不同的就行了。
代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <iostream> #define MAXN 3500010 using namespace std; int ch[MAXN][2],t[MAXN],a[MAXN],sum[MAXN],ans[MAXN]; int n,m,num=1,num2=0; void insert(int x){ for(int i=1;i<=n;i++) t[i]=(x>>(n-i)&1); int now=1; for(int i=1;i<=n;i++){ if(!ch[now][t[i]]) ch[now][t[i]]=++num; now=ch[now][t[i]]; } } void dfs(int now,int shu,int dep){ if(dep<0){ ans[++num2]=shu; return; } if(!ch[now][0]&&ch[now][1]) dfs(ch[now][1],shu^(1<<dep),dep-1); else if(!ch[now][1]&&ch[now][0]) dfs(ch[now][0],shu^(1<<dep),dep-1); else{ dfs(ch[now][0],shu,dep-1); dfs(ch[now][1],shu,dep-1); } } bool cmp(int x,int y){ return x>y; } int b[MAXN]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d",&a[i]); for(int i=m;i>=1;i--) sum[i]=sum[i+1]^a[i]; int x=0; for(int i=0;i<=m;i++){ x=x^((2*a[i])/(1<<n)+2*a[i])%(1<<n); b[i]=x^sum[i+1]; insert(x^sum[i+1]); } dfs(1,0,n-1); sort(ans+1,ans+num2+1,cmp); int cnt=0; for(int i=1;i<=num2;i++){ if(ans[i]==ans[1]) cnt++; } printf("%d\n%d",ans[1],cnt); return 0; }
以上是关于10月10日|9日考试的主要内容,如果未能解决你的问题,请参考以下文章