AtCoder Beginner Contest 222 G
https://atcoder.jp/contests/abc222/tasks/abc222_g
就是扩展BSGS的应用,\(22.....222\)可以看成\(2 * 11.....111\),然后就是\(2 * (100....0000 - 1) / 9 % k = 0\)
//222....222 % k = 0
//转化完就是求2*(10^x-1)/9 mod k = 0
//等于求 10 ^ x mod k*9/gcd(k,2) =1
//p = k * 9 / gcd(k, 2)
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){
x=1,y=0;
return a;
}
ll gcd=exgcd(b,a%b,x,y),temp=x;
x=y,y=temp-a/b*y;
return gcd;
}
ll inv(ll a,ll p){
ll x,y;
if(exgcd(a,p,x,y)!=1) return -1; //无解的情况
return (x%p+p)%p;
}
const int N = 77773;
int hs[N],head[N], nxt[N], id[N],tp;
void insert(int x,int y) {
int k=x%N;
hs[tp] = x,id[tp] = y, nxt[tp] = head[k], head[k] = tp++;
}
int find(int x) {
int k=x%N;
for (int i = head[k]; i != -1; i = nxt[i]) if (hs[i] == x) return id[i];
return -1;
}
ll BSGS(ll a, ll b, ll n) {
memset(head, -1, sizeof head);
tp=1;b%=n;
//if (b == 1)return 0;
ll m = sqrt(n*1.0),x=1,p=1;
for(ll i=0; i<m; ++i,p=p*a%n) insert(p*b%n,i);
for(ll i = m,j;; i+=m) {
if((j=find(x=x*p%n))!=-1) return i-j;
if (i > n) break;
}
return -1;
}
ll EXBSGS(ll a,ll b,ll p){
ll tot=1,cnt=0,g=__gcd(a,p);
a%=p;b%=p; //防止超时
//if(b==1||p==1) return 0;
while(g>1){
if(b%g) return -1; //无法整除则无解
cnt++;b/=g;p/=g;tot=tot*(a/g)%p;
if(tot==b) return cnt; //na=b说明前面的a的次数为0,只需要返回k
g=__gcd(a,p);
}
ll res=BSGS(a,b*inv(tot,p)%p,p);
if(~res) return res+cnt;
return res;
}
void run() {
int k; cin >> k;
k = k * 9;
if(k % 2 == 0) k /= 2;
//10 ^ x % k == 1
cout << EXBSGS(10, 1, k) << '\n';
return ;
}

浙公网安备 33010602011771号