As we all know, operation ”+” complies with the commutative law. That is, if we arbitrarily select two integers a and b, a+b always equals to b+a. However, as for exponentiation, such law may be wrong. In this problem, let us consider a modular exponentiation. Give an integer m=2n and an integer a, count the number of integers b in the range of [1,m] which satisfy the equation
Input
There are no more than 2500 test cases.
Each test case contains two positive integers n and a seperated by one space in a line.
For all test cases, you can assume that
Output
For each test case, output an integer denoting the number of b.
Sample Input
2 3
2 2
Sample Output
1
2
回归日,哒哒~
观察发现当a为奇数时答案均为1。
当a为偶数时:
则记:
则:
因为n<30,所以当 时,计算机暴力验证
当 ,易知
现在看 ,易知
则
当 均满足。
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
long long P(long long a,long long b,long long mod)
{
long long ans=1;
while(b)
{
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
long long p(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b&1)ans*=a;
a*=a;
b>>=1;
}
return ans;
}
int main()
{
long long a,n;
while(scanf("%lld%lld",&n,&a)==2)
{
if(a&1)cout<<1<<endl;
else
{
long long m=1;
for(int i=0;i<n;i++)
m*=2;
long long ans=0;
for(int i=1;i<n;i++)
if(P(a,i,m)==P(i,a,m))ans++;
//cout<<"ans1: "<<ans<<endl;
long long now=1;
for(int i=1;i<=n;i++)
{
now*=2;
if(i*a>=n)
{
//cout<<"i*a: "<<i*a<<endl;
long long temp=1;
for(;;)
{
if(temp*now<n)ans--,temp+=2;
else break;
}//可能包含了前面暴力的部分,所以需要减掉
long long res=p(2,n-i);
if(res>1)ans+=res/2;
else ans++;
}
}
cout<<ans<<endl;
}
}
return 0;
}