一本通1636【例 6】计算器
1636:【例 6】计算器
【输入样例】
3 1
2 1 3
2 2 3
2 3 3
【输出样例】
2
1
2
【提示】
样例输入 2
3 2
2 1 3
2 2 3
2 3 3
样例输出 2
2
1
0
sol:以前看来很水的题目现在已经有点做不动了qaq
三个板子凑起来,随便提一句BSGS
其实只是一种优化的暴力
y^x = z (%Mod)
x = k*B+i (B=sqrt(Mod))
y^(k*B+i) = z (%Mod)
y^(k*B)*(y^i) = z (%Mod)
y^i = z/y^(k*B) (%Mod)
y^i = z*(Inv^k) (Inv = 1/(y^B) )
我还不会exbsgs,只会做Mod是质数的情况
Ps:map自带大常数,所以跑的很慢,这是没办法的事
#include <bits/stdc++.h> using namespace std; typedef long long ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') int T; namespace Ask1 { inline ll Ksm(ll x,ll y,ll Mod) { ll ans=1; while(y) { if(y&1) ans=ans*x%Mod; x=x*x%Mod; y>>=1; } return ans; } inline void Solve() { while(T--) { ll y=read(),z=read(),Mod=read(); Wl(Ksm(y,z,Mod)); } } } namespace Ask2 { /* x*y = z (%Mod) x*y+k*Mod = z (类ax+by=c的形式) */ inline ll gcd(ll x,ll y) { return (!y)?(x):(gcd(y,x%y)); } inline void Exgcd(ll a,ll b,ll &X,ll &Y) { if(b==0) { X=1; Y=0; return; } Exgcd(b,a%b,X,Y); ll XX=X,YY=Y; X=YY; Y=XX-a/b*YY; return; } inline void Solve() { ll a,b,c,r,X,Y; while(T--) { ll y=read(),z=read(),Mod=read(); a=y; b=Mod; c=z; r=gcd(a,b); if(c%r) { puts("Orz, I cannot find x!"); continue; } Exgcd(a,b,X=0,Y=0); X=X*c/r; ll tmp=b/r; X=(X%tmp+tmp)%tmp; Wl(X); } } } /* y^x = z (%Mod) x = k*B+i (B=sqrt(Mod)) y^(k*B+i) = z (%Mod) y^(k*B)*(y^i) = z (%Mod) y^i = z/y^(k*B) (%Mod) y^i = z*(Inv^k) (Inv = 1/(y^B) ) */ namespace Ask3 { map<ll,ll>Map; inline ll Ksm(ll x,ll y,ll Mod) { ll ans=1; while(y) { if(y&1) ans=ans*x%Mod; x=x*x%Mod; y>>=1; } return ans; } inline void Solve() { ll i,j; while(T--) { Map.clear(); ll y=read(),z=read(),Mod=read(); if(y%Mod==0) { puts("Orz, I cannot find x!"); continue; } ll B=sqrt(Mod*1.0),j=1; Map[1]=0; for(i=1;i<=B;i++) { j=j*y%Mod; if(!Map[j]) Map[j]=i; } ll Inv=Ksm(j,Mod-2,Mod); j=1ll; ll ans=-1; for(i=B;(i<=Mod)&&(ans==-1);i+=B) { j=j*Inv%Mod; int oo=Map[z*j%Mod]; if(oo!=0) { ans=i+oo; break; } } (ans==-1)?puts("Orz, I cannot find x!"):(Wl(ans)); } } } int main() { int opt; R(T); R(opt); switch (opt) { case 1: Ask1::Solve(); break; case 2: Ask2::Solve(); break; case 3: Ask3::Solve(); break; default: break; } return 0; } /* input 1 3 146324954 14948940 73162477 output Orz, I cannot find x! */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!