【洛谷九月月賽T1】簽到題(bsgs)(快速乘)
阿新 • • 發佈:2018-09-18
code 是我 好的 取模 lin pri sca ast for
說好的簽到題呢qwq。。。。怎麽我簽到題都不會啊qwq
之後看了bsgs才發現貌似不是那麽那麽難fake!!什麽東西。。。
先貼上部分分做法(也就是枚舉1的個數,然後每一步都進行取模(這和最後取模結果一樣,但是可以處理更大的整數),判斷是否符合題意。這個很好想也很好打,得分70分):
#include<iostream> #include<cstdio> #include<cstring> using namespace std; long long k,m; void ans() { long long x=0; int cnt=0; for(;;) { cnt++; x=(x*10+1)%m; if(x==k) { cout<<cnt<<endl; exit(0); } } } int main() { scanf("%lld%lld",&k,&m); ans(); return 0; }
之後我們可以知道:
顯然an=10n?19a_n=\frac{10^n-1}{9}an?=9
10n?1?
原題等價於10N≡9K+1(modm)10^N\equiv 9K+1\pmod m10N≡9K+1(modm)
之後快速乘+BSGS即可
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<map> using namespace std; typedef long long ll; ll k,m; map<ll,ll> mp; inline ll mul(ll x,ll y,ll mod) { ll tmp=(x*y-(ll)((long double)x/mod*y+1.0e-8)*mod); return tmp<0?tmp+mod:tmp; } //這個是O(1)復雜度的快速乘。。。我在網上抄的,但是我也不太理解是否會出現精度的問題 //但是目前為止貌似是還沒有出過鍋qwq //背模板系列(逃) ll fastpow(ll a,ll x,ll mod){ ll res=1; while(x){ if(x&1){ res=mul(res,a,mod); } x>>=1; a=mul(a,a,mod); } return res; } ll BSGS(ll a,ll b,ll p){ ll m=ceil(sqrt(p)); ll tmp=b; mp.clear(); for(int i=0;i<=m;i++){ mp[tmp]=i; tmp=mul(tmp,a,p); } a=fastpow(a,m,p); tmp=a; for(int i=1;i<=m;i++){ if(mp.count(tmp)) return i*m-mp[tmp]; tmp=mul(tmp,a,p); } return 0; } int main(){ scanf("%lld%lld",&k,&m); k=(k*9+1)%m; printf("%lld\n",BSGS(10,k,m)); return 0; }
【洛谷九月月賽T1】簽到題(bsgs)(快速乘)