zoukankan      html  css  js  c++  java
  • Agc010_D Decrementing

    今天本人因调了上篇博客的题而脑壳不适,不想颓题,因此有了这篇博客。

    但是博客毕竟得讲点什么,想想有没有什么代码短的。

    哦,好像有,就Agc010_D Decrementing好了。

    Alice和Bob又在玩游戏了,这次他们有$N$个数。

    每次操作为:
    1.在所有不小于$2$的数中挑一个减去$1$。
    2.所有数除$d$,$d$为所有数的最大公约数。
    不能操作者输,如果先手必胜则输入$First$,否则输出$Second$。

    其中$Nleq 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(nspace 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;
    }
    

      

  • 相关阅读:
    hadoop 主机名 无法访问问题解决汇总
    Linux 集群时间同步(Ubuntu)
    odoo里面的一些ORM操作
    odoo12动作里添加向导
    odoo看板笔记
    odoo中接口开发
    odoo视图 “动作” 里添加菜单按钮:案例
    odoo源码学习之任务中的阶段字段stage_id
    python中的abstractmethod
    U盘启动盘安装win10出现cdboot:couldn't find ntldr
  • 原文地址:https://www.cnblogs.com/OYJason/p/9629995.html
Copyright © 2011-2022 走看看