HDU - 6189 Law of Commutation(找规律+推公式 17广西邀请赛题)

博客探讨了HDU 6189题目,涉及数论中的找规律和推公式。当a为奇数时,答案固定为1。若a为偶数,通过分析得出b必须为偶数,进一步通过分类讨论和暴力求解计算出符合条件的b数量。由于n较小,对于b>=n的情况,可以通过计算得出最小x,然后求解2^x的倍数。代码实现中注意整数溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

点击打开链接

题意:给定n,a,其中令2^n=m,现求区间[1,m]内有多少个b满足,a^b%m=b^a%m。
首先打表的话可以很容易找到一个规律:a为奇数时,答案肯定为1,这个规律很容易看出就不证了(其实我也不会证 T_T),详细解释一下a为偶数时怎么算,m一定为偶数,所以a^b%m的结果也为偶数,那么b^a%m的结果也必须为偶数,所以b必须为偶数,a既然为偶数那么一定可以写成2*x,所以a^b=2^b*x^b,又m=2^n显然可以发现如果b>=n那么a^b%m一定为0,这个时候就可以分类讨论,由于题目数据中n非常小,所以b<n时直接暴力求解,那么b>=n时这个已经确定a^b%m=0所以我们需要b^a%m同样为0,b为偶数,那么b一定可以表示为2^x*y,那么b^a=2^ax*y^a,我们先令y取得最小1,b^a=2^ax,b^a(2^ax)%m(2^n)=0,所以ax>=n,x>=n/a(注意这里n/a应该向上取整),所以我们就这样找到最小满足条件的x,然后在求出m以内2^x的倍数即可(注意把n以内的答案减去,因为n以内的答案暴力时求过一遍)。还有这题迷之爆int。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<string>
#include<cmath>
#include<stack>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int MAXM=100010;
const long long MOD=1000000007;
const double PI=acos(-1);

long long n,a;

long long qpow(long long x,long long y,long long mod)
{
    long long res=1;
    while(y)
    {
        if (y&1) res=(res*x)%mod;
        x=(x*x)%mod;
        y=y>>1;
    }
    return res;
}
long long qpow(long long x,long long y)
{
    long long res=1;
    while(y)
    {
        if (y&1) res=res*x;
        x=x*x;
        y=y>>1;
    }
    return res;
}
int main()
{
    while(scanf("%lld%lld",&n,&a)!=EOF)
    {
        if (a&1)
        {
            printf("1\n");
            continue;
        }
        else
        {
            long long m=1<<n;
            long long ans=0;
            for (long long i=1;i<=n;i++)
                if (qpow(a,i,m)==qpow(i,a,m))
                ans++;
            long long b2=n/a;
            if (b2*a<n) b2=b2+1;
            long long b3=qpow(2,b2);
            //int b4=qpow(2,a);
            long long res=m/b3-n/b3;
            ans=ans+res;
            printf("%lld\n",ans);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值