P2485 [SDOI2011]计算器
Posted lltyyc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2485 [SDOI2011]计算器相关的知识,希望对你有一定的参考价值。
数论 $2$ 合 $1$
$K=1$ 快速幂,$K=2$ $exgcd$ , $K=3$ $exBSGS$
都是板子就没什么好讲了...
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<map> using namespace std; typedef long long ll; inline int read() int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) if(ch==‘-‘) f=-1; ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); return x*f; inline int ksm(int x,int y,int mo) int res=1; while(y) if(y&1) res=1ll*res*x%mo; x=1ll*x*x%mo; y>>=1; return res; int gcd(int a,int b) return b ? gcd(b,a%b) : a; int exgcd(int a,int b,int &x,int &y) if(!b) x=1,y=0; return a; int d=exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*y; return d; map <int,int> mp; void exBSGS(int X,int Z,int mo) if(Z==1) printf("0\n"); return; int d=gcd(X,mo),t=0,k=1; while(d!=1) if(Z%d) printf("Orz, I cannot find x!\n"); return; t++; Z/=d; mo/=d; k=1ll*k*(X/d)%mo; if(k==Z) printf("%d\n",t); return; d=gcd(X,mo); int m=sqrt(mo)+1; mp.clear(); for(int b=0,s=Z; b<m; b++,s=1ll*s*X%mo) mp[s]=b; for(int a=1,p=ksm(X,m,mo),s=1ll*k*p%mo; a<=m+1; a++,s=1ll*s*p%mo) if(mp.find(s)==mp.end()) continue; printf("%d\n",a*m-mp[s]+t); return; printf("Orz, I cannot find x!\n"); int T,K; int main() T=read(),K=read(); int X,Z,mo; while(T--) X=read(),Z=read(),mo=read(); if(K==1) printf("%d\n",ksm(X,Z,mo)); continue; if(K==3) exBSGS(X,Z,mo); continue; int A=X,B=mo,x,y,d=exgcd(A,B,x,y); if(Z%d) printf("Orz, I cannot find x!\n"); continue; int t=B/d,ans=(1ll*x*(Z/d)%t+t)%t; printf("%d\n",ans); return 0;
以上是关于P2485 [SDOI2011]计算器的主要内容,如果未能解决你的问题,请参考以下文章