重排DL
题解:
https://www.luogu.org/problemnew/show/T51442
从这题上还是学到不少东西。。
以前并没有写过ex-bsgs
正好拿这个复习中国剩余定理和bsgs了(我觉得noip肯定不考这东西)
看过一篇博客说把乘法变除法避免逆元操作
然后我就这么写了 对拍一下会发现是错的
为什么呢
$ a^b=k*a^c\ (\ mod\ m) $ 并不能推导出
$ a^{b-c}=k \ (\ mod\ m) $
只有当m和a互素才成立
所以还是得ex-bsgs
至于ex-bsgs详见xxy https://www.cnblogs.com/TheRoadToTheGold/p/8478697.html
写的很详细了
另外这题还卡常数啊
传统的快速乘并不行
有一种叫做O(1)快速乘的东西
LL modmul(LL A,LL B,LL mod) { return (A*B-(LL)((long double)A*B/mod)*mod+mod)%mod; }
于是我决定明天重新写一下这题。。
代码:
// luogu-judger-enable-o2 #include <bits/stdc++.h> using namespace std; #define IL inline #define rep(i,h,t) for (int i=h;i<=t;++i) #define dep(i,t,h) for (int i=t;i>=h;--i) #define ll long long map<ll,ll> M; ll n,m,b; IL ll cf(ll x,ll y) { ll t=(x*y-(ll)((long double)x*y/m)*m); if (t<0) return t+m; else return t; } ll gcd(ll x,ll y) { if (!y) return(x); return gcd(y,x%y); } ll ksm(ll x,ll y) { if (!y) return(1); if (y==1) return(x); ll ans=ksm(x,y/2); ans=cf(ans,ans); if (y%2==1) ans=cf(ans,x); return ans; } int main() { ios::sync_with_stdio(false); cin>>n>>m>>b; b=((b-n)%m+m)%m; ll a1=((cf(2,n)-1)%m+m)%m; ll tmp=1; ll ans=0; while (1) { ll d=gcd(a1,m); if (d==1) break; if (b%d) { cout<<"INF"<<endl; exit(0); } b/=d; m/=d; ans++; tmp=cf(tmp,a1/d); if (tmp==b) { cout<<ans<<endl; exit(0); } } ll k=sqrt(m); if (k*k<m) k++; ll now=b; rep(i,1,k) { now=cf(now,a1); M[now]=i; } now=tmp; ll a2=ksm(a1,k); rep(i,1,k) { now=cf(now,a2); if (M[now]) { cout<<i*k-M[now]+ans<<endl; exit(0); } } cout<<"INF"<<endl; return 0; }