HDU6189 Law of Commutation (数论)

题意:输入n和a 定义m等于2的n次方 求1-m有多少数使得 a^b = b^a (mod m)

题解:先打表找规律 发现a为奇数的答案只有b = a这一种 (不知道为什么也不想知道为什么

   当a为偶数时 因为m为偶数 所以 a ^ b % m肯定也为偶数 所以 b ^ a % m同理 b也为偶数

   于是a可以写成2*k     a^b可写作 2^b * k^b % (2^n) 显然b >= n时 肯定等于0嘛

   然后分类讨论 b <= n时暴力搞搞

   b > n时 就需要满足 b^a % (2^n)等于0了

   同理就要满足b^a = 2^a * k^a % (2^n)  = 0 那么假设k有x个2 使得(x + 1) * a >= n就好了

   然后所有是这个最小的数倍数的数显然也满足 注意统计答案的时候还要减去暴力算<=n时的答案

总结:反正比赛中是肯定写不出来这个题的

#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;

ll m;
ll pow_mod(ll x, ll y)
{
    ll res = 1;
    while(y)
    {
        if(y & 1) res = res * x % m;
        y >>= 1;
        x = x * x % m;
    }
    return res;
}

int main()
{
    ll n, a;
    while(~scanf("%lld%lld", &n, &a))
    {
        m = (1 << n);
        if(a & 1)
        {
            puts("1");
            continue;
        }
        else
        {
            ll ans = 0;
            for(int i = 1; i <= n; i++)
            {
                ll o = pow_mod(a, i);
                ll u = pow_mod(i, a);
                if(o == u) ans++;
            }

            if(a > n) ans += m / 2 - n / 2;
            else
            {
                ll p;
                if(n % a != 0) p = n / a + 1;
                else p = n / a;

                p = (1LL << p);
                ans += m / p - n / p;
            }
            printf("%lld
", ans);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lwqq3/p/9153511.html