http://poj.org/problem?id=3372
N个人围成一个圈,老师给N个人分糖果.第i次分到的人的编号是f(x) = (x*(x+1)/2)%N,这N个人能不能至少获得1个糖果.
易知必然存在i使得f(N - i - 1) = f(N + i) (mod N), 即周期为N,
只要判断f(x)能否构成N的完全剩余系,就能得出结果
f(x)为N的完全系,即证不存在i,j(i != j),使得f(i) == f(j)
i*(i - 1)/2 = j*(j-1)/2 (mod N)
(i-j)*(i+j+1)/2 = 0 (mod N)
其中(i-j)与(i+j+1)异号.
假设(i-j)为偶数
若(i-j)/2为偶数,当N为S*2^l(S奇数,l > 0),有解
若(i-j)/2为奇数,当N为P*Q,(P,Q是奇数),有解
类似当(i+j+1)为偶数时也一样.
因此N只能是2^l(l > 0)
另外判断n是否为2的k次方
n&(n-1) == 0 true
因为2得n次方得二进制中一定只有1个1
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
const int N = 100000;
bool Num[N];
int main(void)
{
int n;
while(cin>>n)
{
// memset(Num, 0 ,sizeof(Num));
// Num[0] = 1;
// int cnt = 0;
// int count = 0, cur = 0;
// while(cnt <= n)
// {
// cur += cnt;
// cur %= n;
// Num[cur] = 1;
// cnt++;
// }
// int _flag = 1;
// for(int i = 0;i < n;i++)
// if(Num[i] == 0)
// {_flag = 0;break;}
// if(_flag)
// cout<<"Yes"<<endl;
// else
// cout<<"No"<<endl;
printf((n & n - 1) ? "NO\n" : "YES\n");
}
return 0;
}