[洛谷9月月赛]签到题

???签到题???

用BSGS做,但是我没有看见m一定是素数,打了个ExBSGS......

大概意思可以把式子转化成10n≡9*K+1 mod m

然后就是BSGS的板子了

然后因为K,M巨达1011,因此需要用龟速乘。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
long long blo;
map<long long,long long>mp;
long long tor(long long a,long long b,long long mod) {
    long long ans=0;
    while(b) {
        if(b&1) ans=(ans+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return ans;
}
long long ksm(long long d,long long z,long long mod) {
    long long res=1;
    while(z) {
        if(z&1) res=tor(res,d,mod);
        d=tor(d,d,mod);
        z>>=1;
    }
    return res;
}

long long gcd(long long x,long long y) {return y?gcd(y,x%y):x;}
long long bsgs(long long X,long long Z,long long MOD,long long D) {
    blo=ceil(sqrt(MOD+0.5));
    long long tmp=Z,sum=D;
    mp.clear();
    for(int i=1;i<=blo;i++)mp[tmp=tor(tmp,X,MOD)]=i;
    tmp=ksm(X,blo,MOD);
    for(int i=1;i<=blo;i++) {sum=tor(sum,tmp,MOD);if(mp.count(sum))return i*blo-mp[sum];}
    return -1;
}
long long exbsgs(long long X,long long Z,long long MOD) {
    if(Z==1) return 0;
    if(MOD==1) return 0;
    if(!X)return Z==0?1:-1;
    long long D=1,cnt=0;
    for(long long g=gcd(X,MOD);g!=1;g=gcd(X,MOD)) {
        if(Z%g!=0) return -1;
        MOD/=g,Z/=g;
        D=(D,X/g,MOD);cnt++;
        if(D==Z) return cnt;
    }
    X%=MOD;
    long long res=bsgs(X,Z,MOD,D);
    if(res!=-1) return res+cnt;
    return -1;
}
int main() {
    long long K,m;
    cin>>K>>m;
    cout<<exbsgs(10ll,9ll*K+1,m);
}
EXBSGS
我是咸鱼。转载博客请征得博主同意Orz
原文地址:https://www.cnblogs.com/sdfzhsz/p/9662685.html