zoukankan      html  css  js  c++  java
  • bzoj2242

    1. 快速幂

    2. 扩展欧几里得

    3. baby-step-giant-step

    可以自行baidu

    程序附部分注释

      1 const key=1000007;
      2 type link=^node;
      3      node=record
      4        re,wh:longint;
      5        next:link;
      6      end;
      7 
      8 var hash:array[0..key] of link;
      9     a:array[0..100] of longint;
     10     j,g,ans,w,i,n,ch,t,p,z,y:longint;
     11     x,step,k,now:int64;
     12 
     13 function quick(y,z,p:longint):int64;
     14   var t,i:longint;
     15   begin
     16     quick:=1;
     17     t:=0;
     18     while z<>0 do
     19     begin
     20       inc(t);
     21       a[t]:=z mod 2;
     22       z:=z div 2;
     23     end;
     24     for i:=t downto 1 do
     25     begin
     26       quick:=sqr(quick) mod p;
     27       if a[i]=1 then quick:=quick*y mod p;
     28     end;
     29   end;
     30 
     31 function gcd(a,b:longint):longint;
     32   begin
     33     if b=0 then exit(a)
     34     else exit(gcd(b,a mod b));
     35   end;
     36 
     37 procedure exgcd(a,b:longint;var x,y:int64);  //扩展欧几里得
     38   var xx,yy:int64;
     39   begin
     40     if b=0 then
     41     begin
     42       x:=1;
     43       y:=0;
     44     end
     45     else begin
     46       exgcd(b,a mod b,x,y);
     47       xx:=x;
     48       yy:=y;
     49       x:=yy;
     50       y:=xx-(a div b)*yy;
     51     end;
     52   end;
     53 
     54 procedure add(x,i:longint);
     55   var p:link;
     56   begin
     57     w:=x mod key;
     58     p:=hash[w];
     59     while p<>nil do
     60     begin
     61       if p^.re=x then break;
     62       p:=p^.next;
     63     end;
     64     if p=nil then
     65     begin
     66       new(p);
     67       p^.re:=x;
     68       p^.wh:=i;
     69       p^.next:=hash[w];
     70       hash[w]:=p;
     71     end;
     72   end;
     73 
     74 function find(x:longint):longint;
     75   var p:link;
     76   begin
     77     find:=-1;
     78     w:=x mod key;
     79     p:=hash[w];
     80     while p<>nil do
     81     begin
     82       if p^.re=x then exit(p^.wh);
     83       p:=p^.next;
     84     end;
     85   end;
     86 
     87 begin
     88   readln(n,ch);
     89   for i:=1 to n do
     90   begin
     91     readln(y,z,p);
     92     if ch=1 then
     93       writeln(quick(y,z,p))  //快速幂不多说
     94     else if ch=2 then
     95     begin
     96       g:=gcd(y,p);
     97       if z mod g<>0 then   //先判断线性模方程是否有解
     98       begin
     99         writeln('Orz, I cannot find x!');
    100         continue;
    101       end;
    102       y:=y div g;
    103       p:=p div g;
    104       z:=z div g;
    105       exgcd(y,p,x,k);  //转化为二元一次不定方程
    106       x:=((x*z mod p)+p) mod p;  //注意是最小非负数
    107       writeln(x);
    108     end
    109     else begin
    110       z:=z mod p;
    111       t:=trunc(sqrt(p))+1;  当t选址为根号p时时间复杂度最优
    112       for j:=0 to key do
    113         hash[j]:=nil;
    114       now:=1;
    115       add(1,0);
    116       for j:=1 to t do   //求出a^i mod p(0<=i<=t) 的值,并映射到hash上,每个模保留最小的i
    117       begin
    118         now:=now*y mod p;
    119         add(now,j);
    120       end;
    121       g:=gcd(now,p);
    122       if g<>1 then      //求出a^t关于mod p的逆元,没有逆元则无解
    123       begin
    124         writeln('Orz, I cannot find x!');
    125         continue;
    126       end
    127       else begin
    128         now:=now div g;
    129         w:=p div g;
    130       end;
    131       exgcd(now,w,x,k);
    132       x:=(x+w) mod w;
    133       ans:=-1;
    134       step:=z;
    135       for j:=0 to t-1 do
    136       begin
    137         k:=find(step);   //大小步寻找  对于a^it ~ a^(i+1)t-1  (0<=i<=t-1) 寻找可行解
    138 //存在可行解即存在hash中存在模=z*x^i mod p (x表示a^t的逆元) 
    139         if k>-1 then
    140         begin
    141           ans:=k+j*t;
    142           break;
    143         end;
    144         step:=step*x mod p;
    145       end;
    146       if ans=-1 then writeln('Orz, I cannot find x!')
    147       else writeln(ans);
    148     end;
    149   end;
    150 end.
    View Code
  • 相关阅读:
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Python位运算符
  • 原文地址:https://www.cnblogs.com/phile/p/4473172.html
Copyright © 2011-2022 走看看