HDU 6189 Law of Commutation(数论)

201 篇文章 10 订阅

Description

给出两正整数 a,n a , n ,令 m=2n m = 2 n ,对于任意 b[1,m] b ∈ [ 1 , m ] ,求满足 abba(mod m) a b ≡ b a ( m o d   m ) b b 的个数

Input

多组用例,每组用例输入两正整数n,a(1n30,1a109)

Output

对于每组用例,输出满足方程的 b b 的个数

Sample Input

2 3
2 2

Sample Output

1
2

Solution

a为奇数,则 ab mod m a b   m o d   m 为奇数,若 b b 为偶数,则ba mod m为偶数,矛盾,故 b b 为奇数

对于一个奇数x=2k+1 x2=4k2+4k+1=4k(k+1)+1 x 2 = 4 k 2 + 4 k + 1 = 4 k ( k + 1 ) + 1 ,进而 x21(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 ,进而 x41(mod 24) x 4 ≡ 1 ( m o d   2 4 ) ,以此类推有 x2y1(mod 2y+2) x 2 y ≡ 1 ( m o d   2 y + 2 )

aba(mod 23),bab(mod 23) a b ≡ a ( m o d   2 3 ) , b a ≡ b ( m o d   2 3 ) ab(mod 23) a ≡ b ( m o d   2 3 )

abab%4(mod 24),baba%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 ,故有 ab(mod 24) a ≡ b ( m o d   2 4 )

(b,24)=1 ( b , 2 4 ) = 1 ,故 b b 在模24意义下有逆元 b1 b − 1 ,进而有 (ab1)x1(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 ,故有 ab11(mod 24) a b − 1 ≡ 1 ( m o d   2 4 ) ,即 ab(mod 24) a ≡ b ( m o d   2 4 )

以此类推得 ab(mod 2n) a ≡ b ( m o d   2 n ) ,即 b=a%m b = a % m ,这说明解至多一个,而显然 aaaa(mod m) a a ≡ a a ( m o d   m ) ,故解唯一

a a 为偶数,同理可证明b为偶数,由于 ab2b(a2)b(mod 2n) a b ≡ 2 b ⋅ ( a 2 ) b ( m o d   2 n ) ,故当 b>n b > n 时, ab0(mod 2n) a b ≡ 0 ( m o d   2 n ) ,进而 ba0(mod 2n) b a ≡ 0 ( m o d   2 n ) ,对于任意 b[1,m] b ∈ [ 1 , m ] ,将 b b 表示为b=c2x,其中 c c 为奇数,那么有2ax0(mod 2n),此式等价于 axn a x ≥ n ,故 xna x ≥ ⌈ n a ⌉ ,令 x=na x = ⌈ n a ⌉ ,此时区间 (n,m] ( n , m ] 内满足 2x|b 2 x | b b b (m>>x)(n>>x)个,当 bn b ≤ n 时,由于 n30 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;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值