• agc009d


    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
    ");
    	else {
    		if(flag||s1!=1) printf("Second
    ");
    		else if(dfs(1)) printf("First
    ");
    		else printf("Second
    ");
    	}
    	return 0;
    } 
    
  • 相关阅读:
    杨辉三角形
    open live writer
    已加载"C:WindowsSysWOW64msvcp120d.dll".无法查找或打开 PDB 文件.
    4.标准信号与槽
    python的单元测试unittest(一)
    python面向对象--类与对象
    python的文件操作与目录操作os模块
    Jenkins的安装与配置
    selenium切换到iframe
    selenium对富文本的操作
  • 原文地址:https://www.cnblogs.com/patricksu/p/8485930.html
Copyright © 2020-2023  润新知