原题链接

题意简述

给出一个n(n≤105)个数的序列a,足够聪明的AB两人轮流进行以下操作:

令一个大于1的数减1,然后所有数除以gcd{a}。

如果一个人不能操作了,那么他就输了。

输入保证所有数都是正整数并且gcd{a}=1。

分析

这是一道和奇偶性有关的题目。

很容易知道拿到1,1,1,...,1就输了,此时手里数的和sum等于n。

考虑sum奇偶性的转换关系。

或者再展开一点:

偶-奇必然的很好理解,重点考虑一下sum为奇数的情形。

奇(-偶)-奇 要求gcd为偶数,因为偶/奇=偶。因此原数列%2必然是000…01的形式,而我可以将其变为000…11从而形成奇-偶 。所以奇-奇一定条件下可选的,奇-偶任何条件下可行的。

由此再考虑n的奇偶性对答案的影响。

  1. n为偶数

    能保持sum为奇数的一方一定不会输。既然sum一直是奇数,那么就一定不会得到1,1,1,...,1的状态,必胜。而因为拿到奇数的一方一定可以给对手一个偶数,而对手只能无可奈何地还你一个奇数。所以初始sum为奇数则先手必胜,否则必败。

    时间复杂度为O(n)。
  2. n为奇数

    能保持sum为偶数的一方一定不会输。但是拿到偶数的一方需要保证对手不会还回来一个奇数,下面证明这一点一定可以做到。

    证明

    首先奇数方要是想还给对手一个奇数必然要使gcd不为1,所以原数列%gcd必然是000…01的形式。再考虑这个状态是怎么达到的:



    对于000…11,000…02,000…1k,000…0(k+1)这四种状态另一方都有办法规避000…01的结果。所以拿到偶数的一方一定能保证下一轮自己还是偶数。

    因此初始sum为偶数的话先手必胜。

    时间复杂度为O(n)。

    但是初始sum是奇数并不意味着必败;因为此时还没有另一方的干扰,是有可能给对手一个奇数的。但是由于你可能只有极少的选择方案,这给了对手可乘之机:对手也有可能还回来一个奇数。以此循环往复,无法给对手奇数的一方会输掉游戏。

    因为每次都会给所有数除以一个大于1的gcd,所以最多往复log2(min{a})次,其中每次操作的复杂度是O(n)。时间复杂度最大为O(n⋅log2(min{a}))。

总时间复杂度最大为O(n⋅log2(min{a}))。

实现

只有n,sum均为奇数时无法通过判断n和sum的奇偶性来得出答案。

计算出前缀gcdg1和后缀gcdg2,然后计算gcd{g1[i−1],a[i]−1,g2[i+1]},如果 (sum−1)/gcd 为奇数就令所有数除以gcd,然后轮到对手。若没有可能的gcd,GG。

代码

//Decrementing
#include <cstdio>
typedef long long lint;
int const N=1e5+10;
int n,a[N];
int gcd(int x,int y)
{
if(x==-1 || y==-1) return -x*y;
if(x==0) return y;
else return gcd(y%x,x);
}
int g1[N],g2[N];
int main()
{
scanf("%d",&n);
lint sum=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
if(n%2==0)
{
if(sum%2==1) printf("First");
else printf("Second");
return 0;
}
if(sum%2==0) {printf("First"); return 0;}
int cur=0;
while(true)
{
bool flag=false;
sum=0;
for(int i=1;i<=n;i++) sum+=a[i];
g1[0]=-1; g2[n+1]=-1;
for(int i=2;i<=n;i++) g1[i]=gcd(g1[i-1],a[i]);
for(int i=n-1;i>=1;i--) g2[i]=gcd(g2[i+1],a[i]);
int g;
for(int i=1;i<=n&&!flag;i++)
{
if(a[i]==1) continue;
g=gcd(gcd(g1[i-1],g2[i+1]),a[i]-1);
if(((sum-1)/g)%2==1) flag=true;
}
if(flag)
for(int i=1;i<=n;i++) a[i]/=g;
else
{
if(cur==0) printf("Second");
else printf("First");
return 0;
}
cur^=1;
}
return 0;
}

注意

挺好写的,主要是思维难度高

AGC010 - D: Decrementing的更多相关文章

  1. 【AtCoder】AGC010

    AGC010 A - Addition 如果所有数加起来是偶数那么一定可以,否则不行 #include <bits/stdc++.h> #define fi first #define s ...

  2. Agc010_D Decrementing

    今天本人因调了上篇博客的题而脑壳不适,不想颓题,因此有了这篇博客. 但是博客毕竟得讲点什么,想想有没有什么代码短的. 哦,好像有,就Agc010_D Decrementing好了. Alice和Bob ...

  3. [AtCoderContest010D]Decrementing

    [AtCoderContest010D]Decrementing 试题描述 There are \(N\) integers written on a blackboard. The \(i\)-th ...

  4. AGC010

    AGC010 A [过水已隐藏] B 这题推完了还是不会/kk真的毒瘤 考虑每次会减少的总和是\(n(n+1)/2\),用原来的和除以这个可以得到操作次数\(m\)(不是整数无解) 再考虑相邻两个数\ ...

  5. AGC010 - C: Cleaning

    原题链接 题意简述 给出一棵个节点的树,每个点有点权.每次可以选择两个叶节点并将连接它们的路径上的节点的点权-1(包括叶节点).求能否将所有节点的点权都变为0. 分析 先考虑最简单的情况.在这种情况下 ...

  6. AGC010 - B: Boxes

    原题链接 题意简述 给出一个由个数构成的环,每次可以选择一个位置并从这个数起顺时针依次对每个数-1,-2,-3,-,-n.问能否将所有数全变为0. 分析 考虑一次操作对环带来了什么影响. (在后加一个 ...

  7. AGC010 - A: Addition

    原题链接 题意简述 给出一个个数的数列,每次选出两个奇偶性相同的数合成一个数,问最终能否只剩下一个数. 分析 非常简单的一道题. 两个偶数可以合成一个偶数,两个奇数也能合成一个偶数.所以合并偶数时偶数 ...

  8. AGC 010D.Decrementing(博弈)

    题目链接 \(Description\) 给定\(n\)个数\(A_i\),且这\(n\)个数的\(GCD\)为\(1\).两个人轮流进行如下操作: 选择一个\(>1\)的数使它\(-1\). ...

  9. 【AGC010D】Decrementing

    Solution 日常博弈论做不出来. 首先,数值全部为1的局面先手必败. 在接下来的过程中,我们只关注那些大于1的数值. 按照官方题解的思路,首先想一个简化版的问题:没有除的操作,其余相同.那么局面 ...

随机推荐

  1. Python程序的执行方式

    Python代码有两种执行方式: 一.文件执行 二.交互器执行(推荐) 一.文件执行 1.用 notepad++ 或 Sublime Text,甚至 写字本创建一个文件. 2.比如:print('He ...

  2. linkin大话java

    青春不灭,理想犹存,linkin--勿忘初心! 不知不觉已经和java并肩作战将近了2年,在这2年之中模模糊糊研究了java2ee领域的好多东西,但是都没有做系统的整理.以前写的笔记也是零零散散不成一 ...

  3. 错误:java.lang.NoClassDefFoundError: com/project/common/exception/ServiceException 的解决

    问题: 项目编译通过,启动报错误信息java.lang.NoClassDefFoundError: com/project/common/exception/ServiceException. 解决方 ...

  4. 00_HTML入门第二天

    PS切图 快捷键操作无效,原因是没有切换到英文输入状态 常用快捷键新建 CTRL+N       打开 CTRL+O关闭 CTRL+W保存 CTRL+S 另存为 CTRL+SHIFT+S       ...

  5. Nagios状态长时间处于Pending的解决方法

    1 nagios 守护进程引起的一系列问题 1 影响nagios web页面收集监控信息 致使页面出现时而收集不到服务信息 2 影响pnp查看图形化,出图缓慢 3 影响查看服务状态信息,致使有时候查看 ...

  6. matlab判断文件或文件夹是否存在

    当前目录中包含以下文件及文件夹: startup.m win64/ … 判断当前目录中是否存在startup.m文件 if ~exist('startup.m','file')==0    error ...

  7. 2018-01-28-M个本地工作点代码同步到N个GIT远端

    layout: post title: 2018-01-28-M个本地工作点代码同步到N个GIT远端 key: 20180128 tags: IT GIT modify_date: 2018-01-2 ...

  8. ResultSet详细

    1. ResultSet细节1功能:封锁结果集数据操作:如何获得(取出)结果 package com.sjx.a; import java.sql.Connection; import java.sq ...

  9. linux makefile字符串操作函数 替换subst、模式替换patsubst、去首尾空格strip、查找字符串findstring、过滤filter、反过滤filter-out、排序函数sort、取单词word、取单词串wordlist、个数统计words

    1.1       字符操作函数使用 在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能.make所支持的函数也不算很多,不过已经足够我们的操作了.函数调用后,函 ...

  10. Animations and transitions

    在交互式可视化中,有一个词叫reactive,指的是以可视化的方式来响应用户的行为,帮助用户进行可视化并理解其结果.这个很有用.那如何来实现这种交互呢?通过动画. 如果处理得当,动画可以展现出不错的可 ...