Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下:
1. Claris和NanoApe两个人轮流拿石子,Claris先拿。
2. 每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。
不同的初始局面,决定了最终的获胜者,有些局面下先拿的Claris会赢,其余的局面Claris会负。
Claris很好奇,如果这n堆石子满足每堆石子的初始数量是不超过m的质数,而且他们都会按照最优策略玩游戏,那么NanoApe能获胜的局面有多少种。
由于答案可能很大,你只需要给出答案对10^9+7取模的值。
Input
输入文件包含多组数据,以EOF为结尾。
对于每组数据:
共一行两个正整数n和m。
每组数据有1<=n<=10^9, 2<=m<=50000。
不超过80组数据。
Output
Sample Input
3 7
4 13
Sample Output
6
120
Hint
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=2e5+10;
int n,m;
ll a[maxn],rev;
int prime[maxn],tot;
bool isprime[maxn];
ll Pow(ll a,ll b){
ll ans=1;
while (b){
if (b&1)ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
void init(){
rev=Pow(2,mod-2);
tot=0;
for (int i=2;i<=50000;i++){
if (!isprime[i]){
prime[tot++]=i;
}
for (int j=i+i;j<=50000;j+=i)isprime[j]=true;
}
//for (int i=0;i<15;i++)printf ("%d\n",prime[i]);
}
//n是2的幂次方
void FWT(ll a[],int n)
{
for(int d=1;d1)
for(int m=d<<1,i=0;ifor(int j=0;jint x=a[i+j],y=a[i+j+d];
a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
//xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
//and:a[i+j]=x+y;
//or:a[i+j+d]=x+y;
}
}
void UFWT(ll a[],int n)
{
for(int d=1;d1)
for(int m=d<<1,i=0;ifor(int j=0;jint x=a[i+j],y=a[i+j+d];
a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
//xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
//and:a[i+j]=x-y;
//or:a[i+j+d]=y-x;
}
}
void solve(ll a[],int m,int n)
{
FWT(a,m);
for (int i=0;iint main()
{
init();
//printf ("%d\n",Pow(2,5));
while (scanf ("%d%d",&n,&m)!=EOF){
memset (a,0,sizeof (a));
int len=1;while (len<=m)len*=2;
for (int i=0;iprintf ("%lld\n",a[0]);
}
return 0;
}