zoukankan      html  css  js  c++  java
  • HDU

    Law of Commutation 

    题目大意:给你n和a,问在【1,2n】中有多少个b满足 ab%m=ba%m,其中m=2n

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6189

    解题思路:先打表,找一下规律

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll n,a;
    ll qpow(ll a,ll b,ll m)
    {
        ll ans=1;
        a=a%m;
        while(b)
        {
            if(b%2) ans=ans*a%m;
            a=a*a%m;
            b=b/2;
        }
        return ans;
    }
    ll qpow(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b%2) ans=ans*a;
            b=b/2;
            a=a*a;
        }
        return ans;
    }
    int main()
    {
        while(cin>>n>>a)
        {
                ll m=1<<n;
                ll ans=0;
                for(int i=1;i<=m;i++)
                {
                    if(qpow(a,i,m)==qpow(i,a,m)) ans++;
                }
                cout<<ans<<endl;
        }
        return 0;
    }

    我们可以发现,当a为奇数的时候,答案永远是1,所以就需要讨论a是偶数的时候的情况

    若a是偶数则ab也一定是偶数,所以b必须为偶数,则a=2*x ,ab=2b*xb,当b>=n的时候,ab

    %m==0,所以可以找到当b<n的时候有多少符合题意的接,若b>=n,则ba%m==0,b=2x*y

    ba=2ax*ya  %(2n)==0,则此时应使得ax>=n,x>=n/a,因此我们只需要计算出最小的x并求得在m的范围内

    2x的倍数即可

     

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll n,a;
    ll qpow(ll a,ll b,ll m)
    {
        ll ans=1;
        a=a%m;
        while(b)
        {
            if(b%2) ans=ans*a%m;
            a=a*a%m;
            b=b/2;
        }
        return ans;
    }
    ll qpow(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b%2) ans=ans*a;
            b=b/2;
            a=a*a;
        }
        return ans;
    }
    int main()
    {
        while(cin>>n>>a)
        {
            if(a%2==1)
            {
                cout<<"1"<<endl;
                continue;
            }
            else
            {
                ll m=1<<n;
                ll ans=0;
                for(int i=1;i<=n;i++)
                {
                    if(qpow(a,i,m)==qpow(i,a,m)) ans++;
                }
                ll b2=n/a;
                if(b2*a<n) b2++;
                ll b3=pow(2,b2);
                ll res1=m/b3-n/b3;
                cout<<ans+res1<<endl; 
            }
        }
        return 0;
    }

     

  • 相关阅读:
    外包、构件和黑盒抽象等杂想
    C++类型转换小记(一)——C++转换操作符
    大学(一)
    【答】如何获取一个【备份路径】的信息?
    橘色超漂亮滑动二级导航菜单
    CSS自适应宽度按钮
    我们忽略的IE特效——一些特殊效果
    MSSQL 游标示例
    [存]超酷JS拖拽翻页效果
    漂亮的表格
  • 原文地址:https://www.cnblogs.com/tombraider-shadow/p/12170992.html
Copyright © 2011-2022 走看看