zoukankan      html  css  js  c++  java
  • codeforce Hello 2018 913G

    题目大意:给你一个子串,其在2^k方的十进制表示中出现过(后100位),让我们求k(k<10^50)

    原题链接

    SOL :

    a长度为n。 
    可以尝试构造一个数b,使得a10^m+b成为其后缀。

    令  x= a10^m+b,则x=2^k(mod 10^(n+m))

    我们发现 2^(n+m)|x,且 not(5|x),

    我们先枚举m ,令  X= a10^m+b,y=a10^m我们发现y不总是满足上述性质,那么我们就对b做出约束:

      如果 NOT(2^(N+M)|y)  X=y+(2^(N+M)-y%2^(N+M)),

      如果 5|X  ,我们令 X=y+2^(M+N)

    那么我们便把X构造出来了,那么我们就只有一个问题了,那就是怎么求K?

      2^K=X(mod 10^(n+m)),同除上2^(N+M),那么我们得到:

         2^(K-M-N)=X/(2^(N+M))(mod 5^(N+M))

    这个柿子,我们对其取对数,简记R=X/(2^(N+M)) 得到:

       K-M-N=log2 R(mod 5^(N+M))(这一步牵扯到2个知识点:原根 离散对数 )//离散对数先挂着dalao的博客吧,以后有空会补的。

    那么我们的问题就是求log2 R

    我们知道2 是 5 的原根,那么2 也是 5^i 的原根。(不失一般性,我们有 p 是姬(奇)质数,q为其原根,那么q也是 p^l 的原根。l是正整数 )。

    由于数量比较大,传统的baby_step_giant_step算法 过不了,怎么破?传统算法点这里

    那么我们有一个比较厉害的柿子:

        dy,i为模pi意义下的log(g)y,存在 j 满足 di+1=di+j*φ(pi),j[0,p)

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    int len(LL x){int a=0; for (;x;a++,x/=10); return a;}
    LL mul(LL x,LL y,LL mo){
        LL anw=0;
        for (;y>0;y>>=1,x=(x<<1)%mo) 
         if (y&1) (anw+=x)%=mo;
        return anw;
    }
    LL qsm(LL x,LL y,LL mo){
        LL anw=1;
        for (;y>0;y>>=1,x=mul(x,x,mo)) 
         if (y&1) anw=mul(anw,x,mo);
        return anw;
    }
    #define sight(c) ('0'<=c&&c<='9')
    inline void read(int &x){
        static char c;
        for (c=getchar();!sight(c);c=getchar());
        for (x=0;sight(c);c=getchar())x=x*10+c-48;
    }
    inline void read(LL &x){
        static char c;
        for (c=getchar();!sight(c);c=getchar());
        for (x=0;sight(c);c=getchar())x=x*10+c-48;
    }
    void write(LL x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    LL n,l,x,T,tp,mo,y,t,k,p5;
    int main () {
        read(T);
        while (T--) {
            read(k); n=len(k);
            tp=1;
            for (int m=0;;m++) {
                x=k; mo=1ll<<(n+m);
                if (x%mo) x+=mo-x%mo;
                if (!(x%5))x+=mo;
                if ((!(x%mo))&&x%5&&x-k<tp){
                    y=x>>(n+m); t=0; p5=5;
                    if (y%5==1) t=0; if (y%5==2) t=1;
                    if (y%5==3) t=3; if (y%5==4) t=2;
                    for (int i=1;i<n+m;i++){
                        while (qsm(2,t,p5*5)!=y%(p5*5)) t+=p5/5*4;
                        p5*=5;
                    }
                    writeln(t+n+m);
                    break;
                }
                k*=10,tp*=10;
            }
        }
    }

      

  • 相关阅读:
    【知识总结】数学必修二立体几何总结
    【知识总结】数学必修四、必修五三角函数公式总结
    Apache【第一篇】安装
    Nginx【第一篇】安装
    lsb_release 提示命令不存在
    yum 命令提示语法错误
    MySQL【第三篇】数据类型
    MySQL【第二篇】基本命令
    SecureCRT 中 python 命令行使用退格键(backspace)出现 ^H 解决办法
    MySQL【第一篇】安装
  • 原文地址:https://www.cnblogs.com/rrsb/p/8289591.html
Copyright © 2011-2022 走看看