zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    数列分段 II
    Best Cow Fences
    愤怒的牛
    linux 查看文件
    糖果传递
    BL刀片更换主板设置raid
    glance启停
    depot制作
    刀片服务器密码过期, console无法登录解决方案
    DP无法删除失效的多路径链路方法
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9153511.html
Copyright © 2011-2022 走看看