bzoj 2242 [SDOI2011]计算器——BSGS模板
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2242
第一道BSGS!
咳咳,我到底改了些什么?……
感觉和自己的第一版写的差不多……可能是long long还有%C的位置的缘故?
不过挺欣赏这个板子的。把它记下来好了。
其讲解:https://blog.csdn.net/clove_unique/article/details/50740412
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<cmath> #define ll long long using namespace std; ll T,type,A,B,C,x,y; map<ll,ll> mp; ll pw(ll x,ll k,ll mod) { ll ret=1;while(k){if(k&1)ret=ret*x%mod;x=x*x%mod;k>>=1;}return ret; } void exgcd(ll a,ll b,ll &x,ll &y) { if(!b){x=1;y=0;return;} exgcd(b,a%b,y,x);y-=a/b*x; } ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll solve3() { A%=C;B%=C; if(!A) { if(!B)return 1;else return -1; } mp.clear();ll m=ceil(sqrt(C)),t; for(ll i=0;i<=m;i++) { if(!i){t=B%C;mp[t]=i;continue;} t=t*A%C;mp[t]=i;// if cover the previous one,it's correct } t=pw(A,m,C);ll ans=t; for(ll i=1;i<=m;i++) { if(mp[ans])return (i*m%C-mp[ans]%C+C)%C;//%C的位置 ans=ans*t%C; } return -1; } int main() { scanf("%lld%lld",&T,&type); while(T--) { scanf("%lld%lld%lld",&A,&B,&C); if(type==1) { B%=(C-1); printf("%lld\n",pw(A,B,C)); } if(type==2) { ll g=gcd(A,C);//ll g if(B%g){printf("Orz, I cannot find x!\n");continue;} A/=g;C/=g;B/=g; exgcd(A,C,x,y); printf("%lld\n",(x*B%C+C)%C);//多%一个C } if(type==3) { ll ans=solve3(); if(ans==-1)printf("Orz, I cannot find x!\n"); else printf("%lld\n",ans); } } return 0; }