Description
给出两正整数 a,n a , n ,令 m=2n m = 2 n ,对于任意 b∈[1,m] b ∈ [ 1 , m ] ,求满足 ab≡ba(mod m) a b ≡ b a ( m o d m ) 的 b b 的个数
Input
多组用例,每组用例输入两正整数
Output
对于每组用例,输出满足方程的 b b 的个数
Sample Input
2 3
2 2
Sample Output
1
2
Solution
若为奇数,则 ab mod m a b m o d m 为奇数,若 b b 为偶数,则为偶数,矛盾,故 b b 为奇数
对于一个奇数, x2=4k2+4k+1=4k(k+1)+1 x 2 = 4 k 2 + 4 k + 1 = 4 k ( k + 1 ) + 1 ,进而 x2≡1(mod 23) x 2 ≡ 1 ( m o d 2 3 ) , x2=8k+1 x 2 = 8 k + 1 , x4=(8k+1)2=64k2+16k+1 x 4 = ( 8 k + 1 ) 2 = 64 k 2 + 16 k + 1 ,进而 x4≡1(mod 24) x 4 ≡ 1 ( m o d 2 4 ) ,以此类推有 x2y≡1(mod 2y+2) x 2 y ≡ 1 ( m o d 2 y + 2 )
由 ab≡a(mod 23),ba≡b(mod 23) a b ≡ a ( m o d 2 3 ) , b a ≡ b ( m o d 2 3 ) 得 a≡b(mod 23) a ≡ b ( m o d 2 3 )
由 ab≡ab%4(mod 24),ba≡ba%4(mod 24) a b ≡ a b % 4 ( m o d 2 4 ) , b a ≡ b a % 4 ( m o d 2 4 ) ,且 a%4=b%4 a % 4 = b % 4 ,故有 a≡b(mod 24) a ≡ b ( m o d 2 4 )
( (b,24)=1 ( b , 2 4 ) = 1 ,故 b b 在模意义下有逆元 b−1 b − 1 ,进而有 (ab−1)x≡1(mod 24) ( a b − 1 ) x ≡ 1 ( m o d 2 4 ) ,其中 x=a%4 x = a % 4 为奇数,由于 x/|ϕ(24)=23 x ⧸ | ϕ ( 2 4 ) = 2 3 ,故有 ab−1≡1(mod 24) a b − 1 ≡ 1 ( m o d 2 4 ) ,即 a≡b(mod 24) a ≡ b ( m o d 2 4 ) )
以此类推得 a≡b(mod 2n) a ≡ b ( m o d 2 n ) ,即 b=a%m b = a % m ,这说明解至多一个,而显然 aa≡aa(mod m) a a ≡ a a ( m o d m ) ,故解唯一
若 a a 为偶数,同理可证明为偶数,由于 ab≡2b⋅(a2)b(mod 2n) a b ≡ 2 b ⋅ ( a 2 ) b ( m o d 2 n ) ,故当 b>n b > n 时, ab≡0(mod 2n) a b ≡ 0 ( m o d 2 n ) ,进而 ba≡0(mod 2n) b a ≡ 0 ( m o d 2 n ) ,对于任意 b∈[1,m] b ∈ [ 1 , m ] ,将 b b 表示为,其中 c c 为奇数,那么有,此式等价于 ax≥n a x ≥ n ,故 x≥⌈na⌉ x ≥ ⌈ n a ⌉ ,令 x=⌈na⌉ x = ⌈ n a ⌉ ,此时区间 (n,m] ( n , m ] 内满足 2x|b 2 x | b 的 b b 有个,当 b≤n b ≤ n 时,由于 n≤30 n ≤ 30 ,暴力枚举 b b <script type="math/tex" id="MathJax-Element-57">b</script>判方程是否成立即可
Code
#include<cstdio>
using namespace std;
typedef long long ll;
int mod_pow(int a,int b,int c)
{
int ans=1;
while(b)
{
if(b&1)ans=(ll)ans*a%c;
a=(ll)a*a%c;
b>>=1;
}
return ans;
}
int main()
{
int n,a;
while(~scanf("%d%d",&n,&a))
{
int m=1<<n;
if(a&1)printf("1\n");
else
{
int ans=0;
for(int b=2;b<=n;b+=2)
if(mod_pow(a,b,m)==mod_pow(b,a,m))ans++;
int x=(n+a-1)/a;
ans+=(m>>x)-(n>>x);
printf("%d\n",ans);
}
}
return 0;
}