Agc010_D Decrementing
今天本人因调了上篇博客的题而脑壳不适,不想颓题,因此有了这篇博客。
但是博客毕竟得讲点什么,想想有没有什么代码短的。
哦,好像有,就Agc010_D Decrementing好了。
Alice和Bob又在玩游戏了,这次他们有$N$个数。
每次操作为:
1.在所有不小于$2$的数中挑一个减去$1$。
2.所有数除$d$,$d$为所有数的最大公约数。
不能操作者输,如果先手必胜则输入$First$,否则输出$Second$。
其中$N\leq 10^5$,每个数$\leq 10^9$。
乍一看令人十分懵逼,但是我们很容易的发现有几个显然测结论:
1、当最小的数是1时,胜负至于所有数之和$-N$的奇偶性有关
2、有效的除$d$操作不超过$log_210^9=30$次。
我们先定义奇偶性优势:按照每一步操作恰好改变一次奇偶性,最终能获取胜利(即自己操作时有奇数个偶数)。
奇偶性劣势则反之。
然后进一步思考,对于当前操作的人:
若当前的和奇偶性状况对自己有利,则尽量这一奇偶性不改变。我们显然能找到奇数个偶数,对任意一个进行操作之后,$d$一定是个奇数,因此除$d$操作对奇偶性没有影响,并且原先的偶数不会变成奇数,并且会新产生一个奇数。由于任意操作完的局面不可能全是偶数(保证$gcd=1$),因此后手操作的人一定面对至少$2$个奇数,而奇数的数量只会一直增加,因而无论怎么操作$d$均为奇数都无法改变奇偶性劣势,因此必胜。
若当前自己处在奇偶性劣势,则必须考虑通过除$d$操作改变奇偶性。我们发现,这一操作能够实现仅当所有剩余的数中有且仅有一个奇数,且这一奇数大于$1$时才有可能。我们不得不对这个数进行操作,因此会先把原来的奇数减去$1$,使得所有数都为偶数,再新产生至少$1$个奇数。这时我们并不能确定获胜情况,因此我们需要递归地进入下一层。
由于结论$2$,最多会出现$30$层,每层只需要扫一遍,因此最终复杂度是$O(n\space log A_i)$。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 100050
using namespace std;
LL read(){
LL nm=0,fh=1; char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
LL gcd(LL x,LL y){return y==0?x:gcd(y,x%y);}
LL n,p[M],G[M],F[M],sq[31];
void win(LL x){puts(x?"Second":"First");exit(0);}
void solve(LL now){
LL pos=0,sum=0,m=0,tot=0;
for(LL i=1;i<=n;i++) sum+=p[i],m+=(p[i]&1),pos+=(p[i]&1)*i;
if((sum&1)^(n&1)) win(now);
else if((m==1&&p[pos]==1)||m>1) win(now^1);
for(LL i=1;i<=n;i++) tot=gcd(tot,p[i]-(p[i]&1));
for(LL i=1;i<=n;i++) p[i]=(p[i]-(p[i]&1))/tot;
solve(now^1);
}
int main(){
n=read(),sq[0]=1;
for(LL i=1;i<31;i++) sq[i]=sq[i-1]*2ll;
for(LL i=1;i<=n;i++) p[i]=read();
sort(p+1,p+n+1),solve(0);
return 0;
}
Agc010_D Decrementing的更多相关文章
- AGC010 - D: Decrementing
原题链接 题意简述 给出一个个数的序列,足够聪明的AB两人轮流进行以下操作: 令一个大于1的数减1,然后所有数除以. 如果一个人不能操作了,那么他就输了. 输入保证所有数都是正整数并且. 分析 这是一 ...
- [AtCoderContest010D]Decrementing
[AtCoderContest010D]Decrementing 试题描述 There are \(N\) integers written on a blackboard. The \(i\)-th ...
- AGC 010D.Decrementing(博弈)
题目链接 \(Description\) 给定\(n\)个数\(A_i\),且这\(n\)个数的\(GCD\)为\(1\).两个人轮流进行如下操作: 选择一个\(>1\)的数使它\(-1\). ...
- 【AGC010D】Decrementing
Solution 日常博弈论做不出来. 首先,数值全部为1的局面先手必败. 在接下来的过程中,我们只关注那些大于1的数值. 按照官方题解的思路,首先想一个简化版的问题:没有除的操作,其余相同.那么局面 ...
- AtCoder Grand Contest 010 D - Decrementing
题目描述 有n个整数,其中第i个数为Ai.这些数字的gcd为1.两人轮流操作,每次操作把一个大于1的数减1,并把所有数除以所有数的最大公约数,最后无法操作者输,求是否先手必胜. 如果当前的sum为偶数 ...
- AT2305-[AGC010D]Decrementing【博弈论】
正题 题目链接:https://www.luogu.com.cn/problem/AT2305 题目大意 \(n\)个数字两个人进行博弈,每个人的操作为 选择一个大于1的数字减一 之后所有数字除以所有 ...
- ExtJS 4.2 Date组件扩展:添加清除按钮
ExtJS中除了提供丰富的组件外,我们还可以扩展他的组件. 在这里,我们将在Date日期组件上添加一个[清除]按钮,用于此组件已选中值的清除. 目录 1. Date组件介绍 2. 主要代码说明 3. ...
- [LeetCode] Minimum Moves to Equal Array Elements II 最少移动次数使数组元素相等之二
Given a non-empty integer array, find the minimum number of moves required to make all array element ...
- How to step through your code in chrome
By executing code one line or one function at a time, you can observe changes in the data and in the ...
随机推荐
- python 微信跳一跳和源码解读
刚好周末,想研究一下前阵子很火的微信跳一跳 下面进入正文. 本文适用对象为WIN10系统,安卓用户.目的在于让丝毫没有接触过Python的小伙伴都能成功运行,如果你恰好是这样的对象,那么跟着我开始操作 ...
- c# 当前不会命中断点 未载入该文档
C#编码时.有时会遇到标题所说的问题,就是说这个文件和方法明明存在,可总是提示找不到方法.解决方法例如以下: 1.清理全部项目(或相关项目)生成 2.又一次加入全部项目(或相关项目)间的互相引用 3. ...
- vim对光标所在的数字进行增减
真是vim会在不经意间给你惊喜...... 现在发现把光标移到某数字的上方,c-a是加1, c-x是减1 当时真有点众里寻他千百度的感觉
- POJ 1518 A Round Peg in a Ground Hole【计算几何=_=你值得一虐】
链接: http://poj.org/problem?id=1584 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...
- POJ 2965 The Pilots Brothers' refrigerator【枚举+dfs】
题目:http://poj.org/problem?id=2965 来源:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=26732#pro ...
- lua解析json
自己写的lua解析json,带容错,如果要是用于格式检查,得修改下.很简单直接贴代码 --------------------------------------------------json解析- ...
- 我的Android进阶之旅------>Android SDK支持的配置标识符(有用的参考文件)
Android SDK支持的配置标致符 配置标识符 标识符值 描 述 MCC MNC 例子: mcc310: MCC310-MNC004: MCC208-MNC00 MCC(移动国家代码 ...
- LeetCode:乘法表中的第K小的数【668】
LeetCode:乘法表中的第K小的数[668] 题目描述 几乎每一个人都用 乘法表.但是你能在乘法表中快速找到第k小的数字吗? 给定高度m .宽度n 的一张 m * n的乘法表,以及正整数k,你需要 ...
- MD5文件
我从某网站下载了一个iso系统镜像,我担心下载下来之后,被我电脑上的病毒感染了.我要确定这个文件还是“原汁原味”,就可以用软件再次生成该文件的md5码,然后和网站上的md5码对比一下就可以了.我用的是 ...
- ubuntu中文语言环境下把系统中文文件夹更改回英文文件夹
更改系统语言为“汉语(中国)”后,在主文件夹下的系统默认文件夹名称也被改成了中文, 这样的话,使用命令行终端进行入文件夹很不方便,所以可以把文件夹名称从中文改回英文. 打开终端,在终端中输入命令:ex ...