【SDOI2011】计算器[数论 BSGS]

SDOI2011 计算器

[BZOJ2242] [luoguP2485]

1、给定y、z、p,计算y^z mod p 的值;

2、给定y、z、p,计算满足xy ≡z(mod p)的最小非负整数x;

3、给定y、z、p,计算满足y^x ≡z(mod p)的最小非负整数x。

第一个要求直接快速幂

第二个要求因为保证P为质数 直接费马小定理求逆元然后*z

第三个就是BSGS模板

==打的时候1mol错 要注意该加括号的就加括号 不要图简便啥的不加 然后就long long

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<cmath>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;
#define ll long long
#define Abs(x) ((x)<0?-(x):(x))
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
const int N=10000+5,M=20000+5,INF=1e9+7,inf=0x3f3f3f3f;
int y,z,p;
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

int qpow(int a,int b){
	int res=1;
	while(b){
		if(b&1) res=(ll)a*res%p;
		a=(ll)a*a%p,b>>=1;
	}
	return res;
}

map<int,int>hash;
int BSGS(){
	hash.clear();y%=p,z%=p;
	if(!y) return -1;
	int t=(int)sqrt(p)+1;
	for(int j=0,val;j<t;++j)
		val=(ll)z*qpow(y,j)%p,hash[val]=j;
	y=qpow(y,t);
	if(!y) return !z?1:-1;
	for(int i=0,val,j;i<=t;++i){
		val=qpow(y,i);
		j=hash.find(val)==hash.end()?-1:hash[val];
		if(j>=0&&i*t-j>=0) return i*t-j;
	}
	return -1;
}

void work2(){
	if(!(y%p)&&z%p) puts("Orz, I cannot find x!");
	else printf("%lld\n",(ll)qpow(y,p-2)*z%p);
}
void work3(){
	int ans=BSGS();
	if(ans==-1) puts("Orz, I cannot find x!");
	else printf("%d\n",ans);
}

int main(){
	freopen("in.txt","r",stdin);
	int T,K;rd(T),rd(K); 
	while(T--){
		rd(y),rd(z),rd(p);
		if(K==1) printf("%d\n",(qpow(y,z))%p);
		else if(K==2) work2();
		else work3();
	}
	return 0;
}
posted @ 2019-08-30 22:08  委屈的咸鱼鱼鱼鱼  阅读(190)  评论(0编辑  收藏  举报