码迷,mamicode.com
首页 > 其他好文 > 详细

agc009d - Decrementing

时间:2018-02-28 23:01:54      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:class   play   layer   follow   not   can   alter   black   str   

D - Decrementing

Time limit : 2sec / Memory limit : 256MB

Score : 1000 points

Problem Statement

There are N integers written on a blackboard. The i-th integer is *A**i*, and the greatest common divisor of these integers is 1.

Takahashi and Aoki will play a game using these integers. In this game, starting from Takahashi the two player alternately perform the following operation:

  • Select one integer on the blackboard that is not less than 2, and subtract 1 from the integer.
  • Then, divide all the integers on the black board by g, where g is the greatest common divisor of the integers written on the blackboard.

The player who is left with only 1s on the blackboard and thus cannot perform the operation, loses the game. Assuming that both players play optimally, determine the winner of the game.

Constraints

  • 1≦N≦105
  • 1≦*A**i*≦109
  • The greatest common divisor of the integers from A1 through *A**N* is 1.

Solution

唯一确定的先手必胜态为{1,1,1,1,...,2}看出这种状态的基本特征—元素为偶数的个数为奇数。

分类讨论:

  • 偶数有奇数个时,只要保证gcd不为偶数则能保证当前奇偶状态不会发生改变(即保持奇数的个数不为1)

  • 偶数有偶数个时,奇数的个数一定为1时才能逆转奇偶状态,递归解决即可。
    复杂度 因为最差情况下都会除以不为1的gcd,所以最多操作log2(min{a[i]})次

所以最后总复杂度为O(nlog2(min{a[i]}))

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline int read() {
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9') f=(ch=='-')?-1:1,ch=getchar();
    while(ch>='0'&&ch<='9') x=10*x+(ch-'0'),ch=getchar();return x;
}
const int N=1e5+50;
int a[N],n,s0,s1;
int gcd(int x,int y) {return !y?x:gcd(y,x%y);}
bool dfs(int x) {
    int sum=0,flag=0;
    fo(i,1,n) if(a[i]%2) {a[i]--;break;}
    int g=a[1];
    fo(i,2,n) g=gcd(g,a[i]);
    fo(i,1,n)  {
        a[i]/=g;
        if(a[i]%2==0) sum++;
        if(a[i]==1) flag=1;
    }
    if(sum%2) return x^1;
    if(flag||n-sum!=1) return x;
    return dfs(x^1);
}
int main() {
    freopen("1.in","r",stdin);
    bool flag=0;
    n=read();
    fo(i,1,n) {
        a[i]=read(),(a[i]%2)?s1++:s0++;
        if(a[i]==1) flag=1;
    }
    if(s0%2) printf("First\n");
    else {
        if(flag||s1!=1) printf("Second\n");
        else if(dfs(1)) printf("First\n");
        else printf("Second\n");
    }
    return 0;
} 

agc009d - Decrementing

标签:class   play   layer   follow   not   can   alter   black   str   

原文地址:https://www.cnblogs.com/patricksu/p/8485930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!