agc009d - Decrementing

Posted _patrick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了agc009d - Decrementing相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

✔BAD8367模块 500M 45DB可变增益 高线性 低失真 VGA||AGC

✔BAD8367模块 500M 45DB可变增益 高线性 低失真 VGA||AGC

iOS | 零代码快速集成AGC崩溃服务

Android | 零代码快速集成AGC崩溃服务

Android | 零代码快速集成AGC崩溃服务

AGC027 A - Candy Distribution Again