zoukankan      html  css  js  c++  java
  • [Bzoj2242]常见数值算法

    你被要求设计一个计算器完成以下三项任务:
    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)的最小非负整数。
    训练指南的题目,果然光看书不行,动手写才能掌握。
    注意以下几点:
    • exgcd最后的gcd不需要取模
    • 负数的处理 (P+n) mod n
    • int64的使用(防止溢出)
    (**************************************************************
        Problem: 2242
        User: HTwood
        Language: Pascal
        Result: Accepted
        Time:636 ms
        Memory:2568 kb
    ****************************************************************)
     
    program math;
     
    Const
      maxn=100000;
      maxm=2;
      StrErr='Orz, I cannot find x!';
     
    Type
     rec=record
       val,ord:longint;
     end;
     
    var
     p,q,n,m,op,gcd:int64;
     i:longint;
     t:array[0..maxn,0..maxm] of rec;
     
    Function safe(P:int64):int64;inline;
      begin
      exit(((p+n) mod n+n) mod n);
    end;
     
    Function times(p,q:int64):int64;//P^Q (mod N)
      begin
      if q=0 then exit(1);
      times:=times(p,q shr 1);
      times:=safe(times*times);
      if odd(q) then times:=safe(times*p);
    end;
     
    Procedure Exgcd(a,b:int64;var x,y:int64);
      begin
      if b=0 then begin x:=1;y:=0;gcd:=a;exit; end;
      Exgcd(b,a mod b,y,x);
      y:=safe(y-a div b*x);
    end;
     
    Procedure Solve1;inline;//pX+Yn=Q
    var
     x,y:int64;
      begin
      Exgcd(p,n,x,y);
      if q mod gcd<>0 then begin writeln(StrErr); exit; end;
      x:=safe(x);
      writeln(safe((q div gcd)*x));
    end;
     
    Procedure Addhash(val,ord:int64); inline;
    var
     hash,i:longint;
      begin
      hash:=(val mod maxn+maxn) mod maxn;
      for i:=1 to maxm do
        begin
        if t[hash,i].ord>0 then continue;
        t[hash,i].ord:=ord;
        t[hash,i].val:=val;
        break;
      end;
    end;
     
    Function InHash(P:longint;var pos1,pos2:int64):boolean;inline;
    var
     hash,i:longint;
      begin
      hash:=(p mod maxn+maxn) mod maxn;
      for i:=1 to maxm do
        begin
        if t[hash,i].ord=0 then break;
        if t[hash,i].val=p then
          begin
          pos1:=hash;
          pos2:=i;
          exit(true);
        end;
      end;
      exit(false);
    end;
     
    Function inv(P:int64):int64;inline;//pX=1 (mod n)
    var
     x,y:int64;
      begin
      Exgcd(p,n,x,y);
      if gcd=1 then exit((x+n) mod n) else exit(-1);
    end;
     
    Procedure Solve2;inline;//P^x=q (mod n)
    var
     size,v,now,pos1,pos2:int64;
     i:longint;
      begin
      q:=q mod n;
      size:=trunc(sqrt(n))+1;
      fillchar(t,sizeof(t),0);
      v:=inv(times(p,size));
      now:=1;
      for i:=1 to size do
        begin
        now:=(now*p) mod n;
        Addhash(now,i);
      end;
      For i:=0 to size-1 do
        begin
        if inhash(q,pos1,pos2) then
          begin
          writeln((size*i+t[pos1,pos2].ord) mod n);
          exit;
        end;
        q:=(q*v) mod n;
      end;
      Writeln(strErr);
    end;
     
      begin
      readln(m,op);
      for i:=1 to m do
        begin
        readln(p,q,n);
        case op of
          1:writeln(times(p,q));
          2:solve1;
          3:solve2;
        end;
      end;
    end.
    
  • 相关阅读:
    springcloud12-spring cloud stream
    Linux上安装gitbook并拉取git项目编译
    Python 之一条命令生成项目依赖包文件 requirements.txt
    python跨模块使用全局变量的实现方法
    微信朋友圈测试用例
    linux安装maven
    jenkins上集成sonar
    windows上安装sonar并使用其分析项目
    jquery 点击同级元素隐藏,再点击显示
    10进制转16进制自动补全8位 并高低位转换
  • 原文地址:https://www.cnblogs.com/htfy/p/3108975.html
Copyright © 2011-2022 走看看