ToB企服应用市场:ToB评测及商务社交产业平台

标题: AtCoder Beginner Contest 368(ABC368) [打印本页]

作者: 兜兜零元    时间: 2024-8-25 13:52
标题: AtCoder Beginner Contest 368(ABC368)
[ABC368F] Dividing Game

双倍经验。
题意:

有 \(n\) 堆石子,第 \(i\) 堆有 \(a_i\) 颗石子,每次可以拿走恣意一堆石子数量任何数量的棋子,但是要保证拿走之后该堆的石子数量为原来的约数(不能不拿)。
问是先手必胜照旧后手必胜。
\(n,a_i \le 10^5\)。
思路:

发现与 Nim 游戏类似,且全局信息公开,状态有限,故为公平组合游戏。
思量构造必胜状态,设 \(\operatorname{F}(a) = \operatorname{xor}\limits_{i=1}^n \operatorname{f}(a_i)\),若 \(a_i = \prod\limits_{i=1}^k p_i^{q_i} (p_i \in prime)\),则 \(\operatorname{f}(a_i) = \sum\limits_{i=1}^k q_i\)。
手玩后容易发现:
思量证实。
如许我们证实了只有当 \(\operatorname{F}(a) \ne 0\) 时,先手必胜。
那么可以使用线性筛筛出每个数是被哪个质数给筛掉的,就可以快速求出一个数的所有质因子幂次之和
时间复杂度为 \(O(N \log W)\)。
上面是给博弈论小白看的,但是如果您对博弈论颇为纯熟,在发现我们可以将一个数的所有质因子幂次之和变为任何比它小的数时,就转化为了以所有质因子幂次之和为石子数的 Nim 游戏。
Code: [code]#include#define Add(x,y) (x+y>=mod)?(x+y-mod)x+y)#define lowbit(x) x&(-x)#define pi pair#define pii pair#define iip pair#define ppii pair#define fi first#define se second#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x#define Full(a) memset(a,0,sizeof(a))#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);#define For(i,l,r) for(int i=l;i=l;i--)using namespace std;typedef long double lb;typedef double db;typedef unsigned long long ull;typedef long long ll;const ll N=1e5+10;inline ll read(){    ll x=0,f=1;    char c=getchar();    while(c'9'){        if(c=='-')          f=-1;        c=getchar();    }    while(c>='0'&&c A;        }        int g = 0;        for (int i = 0; i < N; i++){                if (A == 1){                        continue;                }                int c = 0;        while(A>1){            A/=F[A];            c++;        }                g ^= c;        }        if (g != 0){                cout =mod)?(x+y-mod)x+y)#define lowbit(x) x&(-x)#define pi pair#define pii pair#define iip pair#define ppii pair#define fi first#define se second#define full(l,r,x) for(auto it=l;it!=r;it++) (*it)=x#define Full(a) memset(a,0,sizeof(a))#define open(s1,s2) freopen(s1,"r",stdin),freopen(s2,"w",stdout);#define For(i,l,r) for(int i=l;i=l;i--)using namespace std;typedef long double lb;typedef double db;typedef unsigned long long ull;typedef long long ll;const ll N=1e5+10;inline ll read(){    ll x=0,f=1;    char c=getchar();    while(c'9'){        if(c=='-')          f=-1;        c=getchar();    }    while(c>='0'&&c




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4