bzoj1411 硬币游戏 分治
来源:互联网 发布:k核分析 社会网络 编辑:程序博客网 时间:2024/06/06 21:03
显然如果令正面=0,反面=1,那么中间硬币的值为两边硬币的异或。然后我们来找规律>_<:
我们首先假设这个序列为a[1],0,a[3],0,a[5],0,a[7],0,a[9],0,a[11],...,然后把每一次的值弄出来(0省略不写,假设a[1]左边是a[-1],a[-1]左边是a[-3]方便找规律):
a[1] a[3] a[5] a[7] a[9] a[11]
a[-1]^a[1] a[1]^a[3] a[3]^a[5] a[5]^a[7] a[7]^a[9] a[9]^a[11]
a[-3]^a[1] a[-1]^a[3] a[1]^a[5] a[3]^a[7] a[5]^a[9] a[7]^a[11] a[9]^a[13]
然后我们发现翻两次之后有:a[i]=a[i-2]^a[i+2],那么我们不妨设不为空的序列比如a[1],a[3],a[5],a[7]把它压成a[1],a[2],a[3],a[4],接下来一次翻两步,就变成:
a[1] a[2] a[3] a[4]
a[0]^a[2] a[1]^a[3] a[2]^a[4] a[3]^a[5]
翻四步第的结果,相当于再翻两下,变成:
a[0]^a[2] a[1]^a[3] a[2]^a[4] a[3]^a[5]
a[-2]^a[4] a[-1]^a[5] a[1]^a[5] a[2]^a[6]。
类似的就可以得到翻8,16,32,64步之后的结果,就可以发现对于任意得k,我们得到翻了2^k以后的结果为
a[i]=a[i-2^(k-1)]^a[i+2^(k-1)]。可以用归纳法证明。
然后就可以根据T的二进制位进行分治了,用类似于快速幂的方式即可。注意当T为奇数时可以先翻一步,然后T=T-1。
AC代码如下:
#include<iostream>#include<cstdio>#include<cstring>#define ll long long#define N 100005using namespace std;int n,a[2][N]; ll m;int main(){scanf("%d%lld",&n,&m); int i,k,flag=0;for (i=1; i<=n; i++){scanf("%d",&a[0][i]); a[0][i]--;}if (m&1){m--; flag=1; a[0][n+1]=a[0][1];for (i=1; i<=n; i++) a[0][i]^=a[0][i+1];}int last=0,now=0;for (m>>=1,k=1; m; m>>=1,k=(k<<1)%n)if (m&1){last=now; now^=1;int x=(n-k)%n+1,y=k+1;for (i=1; i<=n; i++){a[now][i]=a[last][x]^a[last][y];x=x%n+1; y=y%n+1;}}if (flag) printf("0 ");for (i=1; i<n; i++) printf("%d 0 ",a[now][i]+1);if (flag) printf("%d\n",a[now][n]+1); else printf("%d 0\n",a[now][n]+1);return 0;}
by lych
2016.2.27
- bzoj1411 硬币游戏 分治
- bzoj1411: [ZJOI2009]硬币游戏
- bzoj1411: [ZJOI2009]硬币游戏
- bzoj1411 [ZJOI2009]硬币游戏
- bzoj1411: [ZJOI2009]硬币游戏
- bzoj1411: [ZJOI2009]硬币游戏 找规律神题
- bzoj1411
- 硬币游戏
- 硬币游戏
- 硬币游戏
- 分治算法寻找硬币
- 分治解决假硬币问题
- 抛硬币游戏模拟
- 1349 翻硬币游戏
- 猜硬币游戏设计
- 博弈-翻硬币游戏
- 博弈-翻硬币游戏
- 博弈-翻硬币游戏
- 如何快速配置CentOS的时间同步
- iOS中Layer的认识和使用
- 开发常用工具
- 自作農創定을 爲한 全面土地買收計劃
- SQLAlchemy指南(tutorial)
- bzoj1411 硬币游戏 分治
- 判断Fragment是否可见,填坑
- C++: 解释error: call of overloaded ‘abs(int)’ is ambiguous
- 你还在问android横竖屏切换的生命周期?
- Delphi函数详解:全局函数,内部函数,类的成员函数,类的静态方法
- insert插入数据
- 前端样式学习
- 七层登录——C#
- iOS延时操作