HDU4861

来源:互联网 发布:淘宝店铺不装修可以吗 编辑:程序博客网 时间:2024/06/10 09:09

题意:给定k,p,有k个球,每个球的值为1^i+2^i+...+(p-1)^i (mod p) (1 <= i <= k),现在两人轮流取球,最后球的值总和大的人赢,问先手是否能赢
思路:先手不可能输,非赢即平,那么只要考虑每种球的值,
利用费马小定理或欧拉定理,很容易得到该函数的循环节为p - 1,
那么i如果为p - 1的倍数,即为循环节的位置,那么每个值都为1,总和为p - 1
如果i不在循环节的位置,任取一个原根g,根据原根的性质,中包含了1到p - 1,那么原式等同于 那么原式为0
得证原式循环节为p - 1,并且只有循环节上有值,因此只要判断原始的循环节个数是奇数个还是偶数个即可

#include<iostream>//A了,费马定理什么的,数论伤不起 #include<cmath>using namespace std;int main(){int n,p;while(~scanf("%d%d",&n,&p)){if((n/(p-1))&1)cout<<"YES"<<endl;else cout<<"NO"<<endl;}return 0;}


0 0