• POJ2417 Discrete Logging | A,C互质的bsgs算法


    题目:

    给出A,B,C

    求最小的x使得Ax=B  (mod C)


    题解:

    bsgs算法的模板题

    bsgs 全称:Baby-step giant-step

    把这种问题的规模降低到了sqrt(n)级别

    首先B的种类数不超过C种,结合鸽巢原理,所以Ax具有的周期性显然不超过C

    所以一般的枚举算法可以O(C)解决这个问题

    但是可以考虑把长度为C的区间分为k块,每块长度为b

    显然x满足x=bi-p的形式(1<=i<=k,0<=p<b),所以Ax=B  (mod C)移项之后得到Abi=Ap*B (mod C)

    那么这个时候可以预处理出来Ap的所有值(可以用hash表维护)

    //注意!hash表在插入之前要先找有没有这个值,如果有的话直接把改了就好

    处理出Ab的值,枚举i,就可以得到答案

    一般来说令k=b=sqrt(C)时间复杂度最优

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<map>
     5 #include<cmath>
     6 #define MOD 1000007
     7 #define EDGE 500000
     8 typedef long long ll;
     9 using namespace std;
    10 ll c,a,b,ok,m,tmp,t,ans,head[MOD],ecnt;
    11 struct adj
    12 {
    13     ll nxt,w,sum;
    14 }e[EDGE];
    15 void add(ll x,ll sum)
    16 {
    17     ll org=x;
    18     e[++ecnt].w=x;
    19     x%=MOD;
    20     for (int i=head[x];i;i=e[i].nxt)
    21     if (e[i].w==org)
    22     {
    23         e[i].sum=sum;
    24         return ;
    25     }
    26     e[ecnt].sum=sum;
    27     e[ecnt].nxt=head[x];
    28     head[x]=ecnt;
    29 }
    30 ll qow(ll x,ll y,ll P)
    31 {
    32     if (y==0) return 1;
    33     if (y&1) return x*qow(x*x%P,y>>1,P)%P;
    34     return qow(x*x%P,y>>1,P)%P;
    35 }
    36 ll find(ll x)
    37 {
    38     ll org=x;
    39     x%=MOD;
    40     for (int i=head[x];i;i=e[i].nxt)
    41     {
    42     if (e[i].w==org)
    43         return e[i].sum;
    44     }
    45     return -1;
    46 }
    47 int main()
    48 {
    49     while (scanf("%lld%lld%lld",&c,&a,&b)!=EOF)
    50     {
    51     memset(head,0,sizeof(head));
    52     ecnt=0;
    53     ok=0;
    54     if (a%c==0)
    55     {
    56         puts("no solution");
    57         continue;
    58      }
    59     m=ceil(sqrt(c*1.0));
    60     tmp=b%c,add(tmp,0);
    61     if (b==1)
    62     {
    63         printf("0
    ");
    64         continue;
    65     }
    66     for (int i=1;i<m;i++)
    67     {
    68         tmp=tmp*a%c;
    69         add(tmp,i);
    70     }
    71     ll base=qow(a,m,c),tmp=1;
    72     for (int i=1;i<=m;i++)
    73     {
    74         tmp=tmp*base%c;
    75         ans=find(tmp);
    76         if (ans!=-1)
    77         {
    78         printf("%lld
    ",i*m-ans);
    79         ok=1;
    80         break;
    81         }
    82     }
    83     if (!ok)
    84         puts("no solution");
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    基础总结篇之三:Activity的task相关
    基础总结篇之一:Activity生命周期
    基础总结篇之二:Activity的四种launchMode
    SAP_清除默认Action
    FICO_Delete error message
    FICO_无法生成凭证(System status CLSD is active (WBS K/A6020372-205-KCCL))
    FICO_导出8月KOB3报表
    FICO_更改BP
    FICO_月末关帐
    SAP_清除默认导出格式
  • 原文地址:https://www.cnblogs.com/mrsheep/p/7920967.html
Copyright © 2020-2023  润新知