[SDOI2011]计算器
题意
<body> <center> <div style="width:90%; text-align:left"> <img src="image/logo.png"> </div> <table width="96%"> <tbody><tr align="center" class="hd" valign="top"> <th><a href="faqs.php">F.A.Qs</a></th> <th><a href="./">Home</a></th> <th><a href="./bbs.php">Discuss</a></th> <th><a href="./problemset.php">ProblemSet</a></th> <th><a href="./status.php">Status</a></th> <th><a href="./ranklist.php">Ranklist</a></th> <th><a href="./contest.php">Contest</a></th> <th><a href="http://begin.lydsy.com/JudgeOnline">入门OJ</a></th> <th><a href="./modifypage.php"><b>ModifyUser</b></a> <a href="userinfo.php?user=autoint"> <font color="red">autoint</font></a></th><th><a href="logout.php">Logout</a></th> <th><a href="./donation.php"><font color="red">捐赠本站</font></a></th> </tr> </tbody></table> </center> <title>Problem 2242. -- [SDOI2011]计算器</title><center><h2>2242: [SDOI2011]计算器</h2><span class="green">Time Limit: </span>10 Sec <span class="green">Memory Limit: </span>512 MB<br><span class="green">Submit: </span>6231 <span class="green">Solved: </span>2448<br>[<a href="submitpage.php?id=2242">Submit</a>][<a href="problemstatus.php?id=2242">Status</a>][<a href="bbs.php?id=2242">Discuss</a>]</center><h2>Description</h2><div class="content"><div>你被要求设计一个计算器完成以下三项任务:</div> <div>1、给定y,z,p,计算Y^Z Mod P 的值;</div> <div>2、给定y,z,p,计算满足xy≡ Z ( mod P )的最小非负整数;</div> <div>3、给定y,z,p,计算满足Y^x ≡<span> Z ( mod P)</span>的最小非负整数。</div></div><h2>Input</h2><div class="content"><p> 输入包含多组数据。</p> <div>第一行包含两个正整数T,K分别表示数据组数和询问类型(对于一个测试点内的所有数据,询问类型相同)。</div> <div>以下行每行包含三个正整数y,z,p,描述一个询问。</div></div><h2>Output</h2><div class="content"><div>对于每个询问,输出一行答案。对于询问类型2和3,如果不存在满足条件的,则输出“Orz, I cannot find x!”,注意逗号与“I”之间有一个空格。</div></div><h2>Sample Input</h2> <div class="content"><span class="sampledata">【样例输入1】<br> 3 1<br> 2 1 3<br> 2 2 3<br> 2 3 3<br> 【样例输入2】<br> 3 2<br> 2 1 3<br> 2 2 3<br> 2 3 3<br> 【数据规模和约定】<br> 对于100%的数据,1<=y,z,p<=10^9,P为质数,1<=T<=10。</span></div><h2>Sample Output</h2> <div class="content"><span class="sampledata">【样例输出1】<br> 2<br> 1<br> 2<br> 【样例输出2】<br> 2<br> 1<br> 0<br> </span></div><h2>HINT</h2> <div class="content"><p></p></div><h2>Source</h2> <div class="content"><p><a href="problemset.php?search=第一轮day1">第一轮day1</a></p></div><center>[<a href="submitpage.php?id=2242">Submit</a>][<a href="problemstatus.php?id=2242">Status</a>][<a href="bbs.php?id=2242">Discuss</a>]</center><br> <a href="./"><span class="red">HOME</span></a> <a href="javascript:history.go(-1)"><span class="red">Back</span></a>分析
数学题杂糅。
- 快速幂
- exgcd
- bsgs
代码
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
int ksm(int a,int b,int p){
int ans=1%p;
a%=p,b%=p-1;
for(;b;a=(ll)a*a%p,b>>=1)
if(b&1) ans=(ll)ans*a%p;
return ans;
}
int exgcd(int a,int b,int&x,int&y){
if(!b) return x=1,y=0,a;
int d=exgcd(b,a%b,y,x);
return y-=a/b*x,d;
}
int bsgs(int a,int b,int p){
std::map<int,int> H;
b%=p;
int t=sqrt(p)+1;
for(int i=0;i<t;++i) H[(ll)b*ksm(a,i,p)%p]=i;
a=ksm(a,t,p);
if(!a) return b?-1:1;
for(int i=0,val,j;i<=t;++i){
val=ksm(a,i,p),j=H.find(val)==H.end()?-1:H[val];
if(j>=0&&i*t>=j) return i*t-j;
}
return -1;
}
int main(){
// freopen(".in","r",stdin),freopen(".out","w",stdout);
int t=read<int>(),k=read<int>();
for(int y,z,p;t--;){
read(y),read(z),read(p);
if(k==1) printf("%d\n",ksm(y,z,p));
else if(k==2){
int x,t,d=exgcd(y,p,x,t);
if(z%d) puts("Orz, I cannot find x!");
else printf("%lld\n",((ll)x*z/d%p+p)%p);
}
else{
int ans=bsgs(y,z,p);
if(ans==-1) puts("Orz, I cannot find x!");
else printf("%d\n",ans);
}
}
return 0;
}
静渊以有谋,疏通而知事。