zoukankan      html  css  js  c++  java
  • bzoj2242 [SDOI2011]计算器

    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
     
    正解:快速幂+$exgcd$+$BSGS$。
    现在才会$BSGS$,我觉得我要被初三的小学弟超过了。。
    其实还是比较简单的,就是利用了分块的思想,把$a^{x}$拆成$a^{m*i-j}$,其中$m=sqrt{p}$取上整。
    移项以后可以得到$a^{m*i}=b*a^{j}$,于是预处理出$a^{j}$,然后枚举$i$就行了。
     
     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 
     6 using namespace std;
     7 
     8 map <ll,ll> mp;
     9 
    10 il ll gi(){
    11   RG ll x=0,q=1; RG char ch=getchar();
    12   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    13   if (ch=='-') q=-1,ch=getchar();
    14   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    15   return q*x;
    16 }
    17 
    18 il ll qpow(RG ll a,RG ll b,RG ll p){
    19   RG ll ans=1;
    20   while (b){
    21     if (b&1) ans=ans*a%p;
    22     a=a*a%p,b>>=1;
    23   }
    24   return ans;
    25 }
    26 
    27 il ll exgcd(RG ll a,RG ll b,RG ll &x,RG ll &y){
    28   if (!b){ x=1,y=0; return a; }
    29   RG ll t=exgcd(b,a%b,y,x); y-=a/b*x; return t;
    30 }
    31 
    32 int main(){
    33 #ifndef ONLINE_JUDGE
    34   freopen("calc.in","r",stdin);
    35   freopen("calc.out","w",stdout);
    36 #endif
    37   RG ll T=gi(),k=gi();
    38   if (k==1){
    39     while (T--){
    40       RG ll a=gi(),b=gi(),p=gi();
    41       printf("%lld
    ",qpow(a,b,p));
    42     }
    43   }
    44   if (k==2){
    45     while (T--){
    46       RG ll a=gi(),b=gi(),p=gi(),x,y; a%=p,b%=p;
    47       RG ll t=exgcd(a,p,x,y); while (x<0) x+=p;
    48       if (b%t) puts("Orz, I cannot find x!");
    49       else printf("%lld
    ",x*(b/t)%p);
    50     }
    51   }
    52   if (k==3){
    53     while (T--){
    54       RG ll a=gi(),b=gi(),p=gi(),m=ceil(sqrt(p));
    55       a%=p,b%=p; if (!a && !b){ puts("1"); continue; }
    56       if (!a){ puts("Orz, I cannot find x!"); continue; }
    57       mp.clear(); RG ll am=qpow(a,m,p),fg=0;
    58       for (RG ll i=0,t=b;i<m;++i,t=t*a%p) mp[t]=i;
    59       for (RG ll i=1,x=am;i*i<=p+1;++i,x=x*am%p)
    60     if (mp.count(x)){ printf("%lld
    ",i*m-mp[x]),fg=1; break; }
    61       if (!fg) puts("Orz, I cannot find x!");
    62     }
    63   }
    64   return 0;
    65 }
  • 相关阅读:
    正在与拖延症病魔抗争中
    Words For Today [20110724]
    短期目标[Till 20110805]
    Words For Today [20110804]
    Words For Today [20110731]
    Words For Today [20110801]
    Words For Today [20110723]
    《定位》一书
    马云的最近的话柱着拐杖跳高
    创业的人格
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7523090.html
Copyright © 2011-2022 走看看