Law of Commutation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 469 Accepted Submission(s): 172
Problem Description
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
ab≡ba (mod
m).
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 n≤30,1≤a≤109.
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 n≤30,1≤a≤109.
Output
For each test case, output an integer denoting the number of
b.
Sample Input
2 3 2 2
Sample Output
1 2
题意:输入n,a,令m = 2^n,问b取[1,m],问有多少个这样的b使(a^b)%m=(b^a)%m.
思路:找规律发现当a为奇数的时候,答案恒为1,当a为偶数,a^b为偶数,为使b^a为偶数,b也必须为偶数.
因为n比较小,所以当b小于等于n的时候可以暴力判断,当b> n,(a^b)%m恒为0,所以我们想使(b^a)%m也为0.
因为m = 2^n,所以b^a应为m的倍数,所以b应为2^(n/a)的倍数,此处上取整.所以我们只需算一下m是2^(n/a)的多少倍即可.当然还得减去<= n范围内重复的数量.
代码:
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
const double eps = 1e-12;
const int inf = 0x3f3f3f3f;
map<int,int>::iterator it;
ll n;
ll a,b,mod;
ll quick_pow(ll x,ll y)
{
ll ans = 1;
while(y)
{
if(y&1)
ans = ans*x%mod;
y>>= 1;
x = x*x%mod;
}
return ans;
}
int main()
{
while(~scanf("%lld %lld",&n,&a))
{
if(a&1)
{
printf("1\n");
continue;
}
mod = 1<<n;
ll ans = 0;
for(ll i = 2;i<= n;i+= 2)
{
if(quick_pow(a,i) == quick_pow(i,a))
ans++;
}
ll tmp = (n+a-1)/a;//上取整
tmp = 1<<tmp;
ans+= (mod/tmp-n/tmp);//减去重复的
printf("%lld\n",ans);
}
return 0;
}