zoukankan      html  css  js  c++  java
  • 洛谷P2485 [SDOI2011]计算器(exgcd+BSGS)

    传送门

    一题更比三题强

    1操作直接裸的快速幂

    2操作用exgcd求出最小正整数解

    3操作用BSGS硬上

    然后没有然后了

     1 //minamoto
     2 #include<cstdio>
     3 #include<map>
     4 #include<cmath>
     5 #include<iostream>
     6 #define ll long long
     7 using namespace std;
     8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     9 char buf[1<<21],*p1=buf,*p2=buf;
    10 inline ll read(){
    11     #define num ch-'0'
    12     char ch;bool flag=0;ll res;
    13     while(!isdigit(ch=getc()))
    14     (ch=='-')&&(flag=true);
    15     for(res=num;isdigit(ch=getc());res=res*10+num);
    16     (flag)&&(res=-res);
    17     #undef num
    18     return res;
    19 }
    20 inline ll ksm(ll a,ll b,ll p){
    21     ll res=1;
    22     while(b){
    23         if(b&1) (res*=a)%=p;
    24         (a*=a)%=p,b>>=1;
    25     }
    26     return res;
    27 }
    28 ll exgcd(ll a,ll b,ll &x,ll &y){
    29     if(!b){x=1,y=0;return a;}
    30     ll d=exgcd(b,a%b,x,y);
    31     ll t=x;x=y,y=t-y*(a/b);
    32     return d;
    33 }
    34 map<ll,ll> mp;
    35 ll BSGS(ll a,ll b,ll p){
    36     mp.clear();
    37     b%=p;int t=sqrt((double)p)+1,tot=1;
    38     for(int j=0;j<t;++j){
    39         int val=b*tot%p;
    40         mp[val]=j,tot=tot*a%p;
    41     }
    42     if(!tot) return b==0?1:-1;
    43     a=tot,tot=1;
    44     for(int i=0;i<=t;++i){
    45         int j=mp.find(tot)==mp.end()?-1:mp[tot];
    46         if(j>=0&&i*t-j>=0) return i*t-j;
    47         tot=tot*a%p;
    48     }
    49     return -1;
    50 }
    51 ll t,k,z,y,p;
    52 void solve1(){
    53     while(t--){
    54         y=read(),z=read(),p=read();
    55         printf("%lld
    ",ksm(y,z,p));
    56     }
    57 }
    58 void solve2(){
    59     while(t--){
    60         y=read(),z=read(),p=read();
    61         ll x=0,yy=0,d=0;
    62         d=exgcd(y,p,x,yy);
    63         if(z%d!=0){puts("Orz, I cannot find x!");}
    64         else{
    65             ll tmp=abs(p/d);
    66             x=(((x*z)/d)%tmp+tmp)%tmp;
    67             printf("%lld
    ",x);
    68         }
    69     }
    70 }
    71 void solve3(){
    72     while(t--){
    73         y=read(),z=read(),p=read();
    74         ll ans=BSGS(y,z,p);
    75         if(ans!=-1) printf("%lld
    ",ans);
    76         else puts("Orz, I cannot find x!");
    77     }
    78 }
    79 int main(){
    80 //    freopen("testdata.in","r",stdin);
    81     t=read(),k=read();
    82     switch(k){
    83         case 1:solve1();break;
    84         case 2:solve2();break;
    85         case 3:solve3();break;
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    二进制,八进制,十六进制,十进制之间的换算
    14简化路径(71)
    13字符串解码(394)
    12 反转每对括号间的子串(1190)
    11 使括号有效的最少添加(921)
    10 K 个一组翻转链表(25)
    9 从链表中删去总和值为零的连续节点(1171)
    8 链表中的下一个更大节点(1019)
    7两两交换链表中的节点(24)
    6 奇偶链表(
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9740717.html
Copyright © 2011-2022 走看看