BZOJ 1411&&Vijos 1544 : [ZJOI2009]硬币游戏【递推,快速幂】
1411: [ZJOI2009]硬币游戏
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 897 Solved: 394
Description
Orez很喜欢玩游戏,他最近发明了一款硬币游戏。他在桌子的边缘上划分出2*n个位置并按顺时针把它们标号为1,2,……,2n,然后把n个硬币放在标号为奇数的位置上。接下来每次按如下操作:在任意两个硬币之间放上一个硬币,然后将原来的硬币拿走;所放硬币的正反面由它两边的两个硬币决定,若两个硬币均为正面朝上或反面朝上,则所放硬币为正面朝上,否则为反面朝上。 那么操作T次之后桌子边缘上硬币的情况会是怎样的呢?
Input
文件的第一行包含两个整数n和T。 接下的一行包含n个整数,表示最开始桌面边缘的硬币摆放情况,第i个整数ai表示第i个硬币摆放在2*i-1个位置上,ai=1表示正面朝上,ai=2表示反面朝上。
Output
文件仅包含一行,为2n个整数,其中第i个整数bi桌面边缘的第i个位置上硬币的情况,bi=1表示正面朝上,bi=2表示反面朝上,bi=0表示没有硬币。
Sample Input
10 5 2 2 2 1 1 1 1 1 1 2
Sample Output
0 1 0 1 0 1 0 1 0 2 0 1 0 2 0 1 0 1 0 1 数据范围 30%的数据 n≤1000 T≤1000 100%的数据 n≤100000 T≤2^60
HINT
Source
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1411或者https://vijos.org/p/1554
题目大意:给定一圈硬币,T次操作,每次操作在每个硬币中间各放一枚硬币,硬币的正反面由它旁边两个决定,两边相同则为正面,两边不相同则为反面,然后将之前的硬币全部撤掉,问T次操作后的硬币序列,T<=2^60
首先我们令硬币正面为0 反面为1 那么很容易发现新硬币的值为两边硬币的异或值 样例也就很好解释了
1-1-1-0-0-0-0-0-0-1- 0 -0-0-1-0-0-0-0-0-1-0 1 0-0-1-1-0-0-0-0-1-1- 2 -0-1-0-1-0-0-0-1-0-1 3 1-1-1-1-1-0-0-1-1-1- 4 -0-0-0-0-1-0-1-0-0-0 5
然后这题n<=10W 矩阵乘法一定MLE 即使矩阵特殊构造可以干掉一维空间复杂度 O(n^2*logT)的时间也无法承受
我们只考虑偶数的行
易知第二行每个数是原序列该位置左右两个数的异或
由数学归纳法可以 第2^k行每个数是原序列该位置左侧第2^(k-1)个数和右侧第2^(k-1)个数的异或
然后将T进行二进制拆分,每位进行一次变换即可 最后再讨论T的奇偶
时间复杂度O(n*logT)
膜拜出题人,膜拜题解人,这TM也成,我服了!
下面给出AC代码:
1 #include <bits/stdc++.h>
2 #define in freopen("coin.in","r",stdin);
3 #define out freopen("coin.out","w",stdout);
4 #define M 100100
5 using namespace std;
6 typedef long long ll;
7 ll n,T,tot;
8 char a[2][M],ans[M<<1];
9 inline ll read()
10 {
11 ll x=0,f=1;
12 char ch=getchar();
13 while(ch<'0'||ch>'9')
14 {
15 if(ch=='-')
16 f=-1;
17 ch=getchar();
18 }
19 while(ch>='0'&&ch<='9')
20 {
21 x=x*10+ch-'0';
22 ch=getchar();
23 }
24 return x*f;
25 }
26 int main()
27 {
28 ll i,j,x;
29 n=read();
30 T=read();
31 for(i=1;i<=n;i++)
32 {
33 x=read();
34 a[0][i]=x-1;
35 }
36 for(j=2;j<=T;j<<=1)
37 {
38 if(T&j)
39 {
40 tot++;
41 for(i=1;i<=n;i++)
42 {
43 ll x1=(i+(j>>1)%n+n-1)%n+1;
44 ll y1=(i-(j>>1)%n+n-1)%n+1;
45 a[tot&1][i]=a[~tot&1][x1]^a[~tot&1][y1];
46 }
47 }
48 }
49 for(i=1;i<=n;i++)
50 {
51 ans[i+i-1]=a[tot&1][i];
52 }
53 if(T&1)
54 {
55 for(i=1;i<=n;i++)
56 {
57 ans[i<<1]=ans[i+i-1]^ans[i==n?1:i<<1|1];
58 }
59 for(i=1;i<=n;i++)
60 {
61 ans[i+i-1]=-1;
62 }
63 }
64 else
65 {
66 for(i=1;i<=n;i++)
67 {
68 ans[i+i]=-1;
69 }
70 }
71 for(i=1;i<=n<<1;i++)
72 {
73 printf("%d%c",ans[i]+1,i==n+n?'n':' ');
74 }
75 return 0;
76 }
以上方法我还是有点迷,下面换种写法,
对于样例,进行数学归纳,发现2^k变换之后,第i个位置的硬币情况只与它左右的第k+1个硬币有关。
如k=0,第3位硬币情况只与2和4位硬币有关。因为t可以拆成若干个2^k的和,于是对每个2^k进行O(n)的变换,总复杂度O(nlogt)。
1 #include <bits/stdc++.h>
2 #define in freopen("coin.in","r",stdin);
3 #define out freopen("coin.out","w",stdout);
4 typedef long long ll;
5 using namespace std;
6 inline ll read()
7 {
8 ll x=0,f=1;
9 char ch=getchar();
10 while(ch<'0'||ch>'9')
11 {
12 if(ch=='-')
13 f=-1;
14 ch=getchar();
15 }
16 while(ch>='0'&&ch<='9')
17 {
18 x=x*10+ch-'0';
19 ch=getchar();
20 }
21 return x*f;
22 }
23 const int N=200020;
24 ll n,t,a[N],b[N];
25 ll f(ll b,ll k)
26 {
27 ll x=b-k;
28 ll y=b+k;
29 x=(x%(n<<1)+(n<<1)-1)%(n<<1)+1;
30 y=(y-1)%(n<<1)+1;
31 if(k==0)
32 return a[x];
33 if(a[x]==0)
34 return 0;
35 if(a[x]==a[y])
36 return 1;
37 else return 2;
38 }
39 void work(ll k,ll q)
40 {
41 if(k==0)
42 return;
43 work(k>>1,q<<1);
44 if(k%2==1)
45 {
46 memset(b,false,sizeof(b));
47 for(ll j=1;j<=(n<<1);j++)
48 b[j]=f(j,q);
49 swap(a,b);
50 }
51 }
52 int main()
53 {
54 n=read();
55 t=read();
56 for(ll i=1;i<=n;i++)
57 a[(i<<1)-1]=read();
58 work(t,1);
59 for(ll i=1;i<(n<<1);i++)
60 cout<<a[i]<<" ";
61 cout<<a[n<<1]<<endl;
62 return 0;
63 }
- KVO、Delegate、Notification 区别及相关使用场景你要知道的KVC、KVO、Delegate、Notification都在这里
- Core ML简介及实时目标检测及Caffe TensorFlow coremltools模型转换
- iOS网络——NSURLSession详解及SDWebImage源码解析你要知道的NSURLSession都在这里
- BZOJ3585: mex(主席树)
- 01.LoT.UI 前后台通用框架分解系列之——小图片背景全屏显示(可自动切换背景)
- 02.LoT.UI 前后台通用框架分解系列之——灵活的菜单栏
- 05.LoT.UI 前后台通用框架分解系列之——漂亮的时间选择器
- 06.LoT.UI 前后台通用框架分解系列之——浮夸的图片上传
- 07.LoT.UI 前后台通用框架分解系列之——轻巧的文本编辑器
- 07.LoT.UI 前后台通用框架分解系列之——强大的文本编辑器
- 洛谷P3358 最长k可重区间集问题(费用流)
- 08.LoT.UI 前后台通用框架分解系列之——多样的Tag选择器
- iOS多线程——RunLoop与GCD、AutoreleasePool你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里
- iOS多线程——你要知道的RunLoop都在这里你要知道的iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 别忘了给gcc编译器工具链加上-fno-common选项
- 轻量安全的部署方案
- 算法集锦(34) | 强化学习| 出租车载客问题
- 前端测试题:(解析)关于ajax跨域的说法,下面错误的是?
- 什么才是定制化 IDE 的核心价值?
- RTOS内功修炼记(八)— CMSIS RTOS API,内核通用API接口
- 从零搭建Spring Boot脚手架(1):开篇以及技术选型
- 盘点 Python 10 大常用数据结构(下篇)
- 「干货」你需要了解的六种渲染模式
- 分享两个操作Java枚举的实用方法
- 从零开始强化学习:在Python笔记本中设计和解决一个任务
- 基于深度学习的新闻推荐算法(1)
- 以复现图表的方式来学习一篇文章
- 盘点 Python 10 大常用数据结构(上篇)
- (长文预警) 你还在烦工作中碰到的拖拽问题?一个框架jiejue