• 【BZOJ2242】【SDoi2011】计算器 快速幂+EXGCD+BSGS


    Description

    你被要求设计一个计算器完成以下三项任务:
    1、给定y,z,p,计算Y^Z Mod P 的值;
    2、给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数;
    3、给定y,z,p,计算满足Y^x ≡ Z ( mod P)的最小非负整数。

    Input

     输入包含多组数据。

    第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。
    以下行每行包含三个正整数y,z,p,描述一个询问。

    Output

    对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。

    Sample Input

    【样例输入1】
    3 1
    2 1 3
    2 2 3
    2 3 3
    【样例输入2】
    3 2
    2 1 3
    2 2 3
    2 3 3
    【数据规模和约定】
    对于100%的数据,1<=y,z,p<=10^9,为质数,1<=T<=10。

    Sample Output

    【样例输出1】
    2
    1
    2
    【样例输出2】
    2
    1
    0

    HINT

     

    Source

    Solution:第一问快速幂
          第二问EXGCD
          第三问BSGS
    BSGS(Baby Step Giant Step)网上介绍的很详细了,但是我令x=im-j这样就不用求逆元辣,相应的为了不出现负数是i从1开始到m枚举,则j从1到m枚举,因为可以等于m,j就不需要从0开始啦.。
    另:一开始在CV上测,用了puts试试,忘了自带换行在CV上过了,然而在BZOJ PE了233
     1  
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cmath>
     5 #include <map>
     6 #define ll long long 
     7 using namespace std;
     8 ll y,z,p;
     9  
    10 ll fast_pow(ll y,ll z,ll p)
    11 {
    12     ll ans=1;
    13     while (z)
    14     {
    15         if (z&1)    ans=ans*y%p;
    16         y=y*y%p;
    17         z>>=1;
    18     }
    19     return ans;
    20 }
    21  
    22 ll gcd(ll a,ll b)
    23 {return b==0?a:gcd(b,a%b);}
    24  
    25 void ex_gcd(ll a,ll b,ll &x,ll &y)
    26 {
    27     if (!b) {x=1;y=0;return;}
    28     ex_gcd(b,a%b,x,y);
    29     ll t=x; x=y; y=t-a/b*y; 
    30 }
    31  
    32 void solve1()
    33 {
    34     printf("%lld
    ",fast_pow(y,z,p));
    35 }
    36  
    37 void solve2()
    38 {
    39     ll d=gcd(y,p);
    40     if (z%d)    {printf("Orz, I cannot find x!
    ");return;}
    41     y/=d; z/=d;
    42     ll a,b;
    43     ex_gcd(y,p,a,b);
    44     a=a*z%p;
    45     while (a<0)  a+=p;
    46     printf("%lld
    ",a);
    47 }
    48  
    49 void solve3()
    50 {
    51     y%=p,z%=p;
    52     if (!y && !z)   {puts("1"); return;}
    53     if (!y) {printf("Orz, I cannot find x!
    ");return;}
    54     map<ll,ll> mp;
    55     mp.clear();
    56     ll m=ceil(sqrt(p));
    57     ll t=fast_pow(y,m,p),k=z%p;//直接m即可 
    58     for (int i=0;i<m;i++)
    59     {
    60         if (!mp[k]) if (i) mp[k]=i;//注意变量,及时订正。 
    61                     else mp[k]=-1;
    62         k=k*y%p;
    63     }
    64     k=1;
    65     for (int i=0;i<m;i++)
    66     {
    67         if (mp[k])//注意!mp与mp的判断 
    68         {
    69             if (mp[k]==-1)  mp[k]=0;
    70             printf("%lld
    ",i*m-mp[k]);
    71             return;
    72         }
    73         k=k*t%p;
    74     }
    75     printf("Orz, I cannot find x!
    ");//各种傻 
    76 }
    77  
    78 int main()
    79 {
    80     int T,t;
    81     scanf("%d%d",&T,&t);
    82     while (T--)
    83     {
    84         scanf("%lld%lld%lld",&y,&z,&p);
    85         if (t==1)   solve1();
    86         if (t==2)   solve2();
    87         if (t==3)   solve3();
    88     }
    89 }
    View Code
    —Anime Otaku Save The World.
  • 相关阅读:
    hive sql基础了解
    创建自增字段,修改字段
    flysql 里两种传参的方式
    创建有赞商品资料
    cortable 使用方法
    学会如何使用,pycharm,和gitlanb
    进程和线程
    创建商品资料模板
    SAP 实例 5 CFW Events
    SAP 实例 4 CFW
  • 原文地址:https://www.cnblogs.com/DMoon/p/5225450.html
Copyright © 2020-2023  润新知