[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>&nbsp;&nbsp;<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&nbsp;&nbsp;<span class="green">Memory Limit: </span>512 MB<br><span class="green">Submit: </span>6231&nbsp;&nbsp;<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>&nbsp;输入包含多组数据。</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&lt;=y,z,p&lt;=10^9,P为质数,1&lt;=T&lt;=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>
</body>

分析

数学题杂糅。

  1. 快速幂
  2. exgcd
  3. 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;
}

posted on 2019-04-03 17:32  autoint  阅读(110)  评论(0编辑  收藏  举报

导航