zoukankan      html  css  js  c++  java
  • 板子

    题目描述

    已知数a,p,b,求满足a^x≡b(mod p)的最小自然数x。

    输入输出格式

    输入格式:

    每个测试文件中最多包含100组测试数据。

    每组数据中,每行包含3个正整数a,p,b。

    当a=p=b=0时,表示测试数据读入完全。

    输出格式:

    对于每组数据,输出一行。

    如果无解,输出“No Solution”(不含引号),否则输出最小自然数解。

    输入输出样例

    输入样例#1: 复制
    5 58 33
    2 4 3
    0 0 0
    输出样例#1: 复制
    9
    No Solution

    说明

    100%的数据,a,p,b≤1e9。




    xkt×xtdi=ydi(modpdi)
    #include"bits/stdc++.h"
    using namespace std;
    
    typedef long long ll;
    unordered_map <ll,ll> mp;
    
    ll a,b,p;
    
    
    ll bsgs(ll a,ll b,ll p)
    {
       if(b==1)return 0; ll d; ll k=1; int cnt=0;
    
       while ((d=__gcd(a,p))^1)
       {
          if(b%d)return -1; // 不能整除,return ;
          b/=d; p/=d;cnt++;
          k=1ll*k*(a/d)%p;
          if(k==b)return cnt;   // a/d 的乘积等于现在的b,然后就能约掉,左边x取cnt,为0次幂
    
           // cout<<k<<" "<<a<<" "<<b<<" "<<p<<endl;
       }
    
    
    
       int m=sqrt(p)+1; ll kt=1;
       mp.clear();
       for (int i=0;i<m;i++)// 左边小步
       {
         mp[1LL*kt*b%p]=i;
         kt=kt*a%p; // 这里最后kt是a^ml
    
       }
    
       k=k*kt%p;
    
       for (int i=1;i<=m;i++)// 右边大步
       {
         if(mp.find(k)!=mp.end()) return i*m-mp[k]+cnt; // 查表
         k=k*kt%p;
       }
    
       return -1;
    
    }
    
    int main()
    {
       while (cin>>a>>p>>b)
       {
           if(!a&&!b&&!p)break;
        //   cout<<123<<endl;
          ll ans=bsgs(a,b,p);
          if(ans!=-1)printf("%lld
    ",ans);
          else puts("No Solution");
        //  cout<<123<<endl;
    
       }
    
    }
     
     
     
     
  • 相关阅读:
    文件操作2
    操作文件1
    标准库(一):collections之orderedDict
    类的模板导入
    类的继承
    类内成员和方法的使用
    redis高可用
    oracle数据库优化
    如何捕获oracle数据库异常
    oracle之语句触发器创建
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10404458.html
Copyright © 2011-2022 走看看