ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

#费马小定理,BSGS#BZOJ 3285 离散对数解指数方程

2021-09-25 08:01:08  阅读:168  来源: 互联网

标签:BSGS return GCD rr int lll 3285 mod BZOJ


题目

求最小的正整数 \(x\) 满足 \(g^{ax+b}\equiv c\pmod p\)
其中 \(p\) 是一个质数, \(g,a,b,c\leq 10^{1000000},p\leq 2^{31}\)


分析

先将 \(g^a\)和 \(g^b\) 用费马小定理求出来,

问题就转换成 \(b'\times {a'}^x\equiv c'\pmod p\)

这个直接套用 BSGS 就可以了


代码

#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#define rr register
using namespace std;
const int p=70001; typedef long long lll;
const int N=1000011; char A[N],B[N],C[N],G[N];
lll mod,lA,lB,lC,ans,lG,a,b,c,g;
struct Linked_Hash{
	struct node{int y,w,next;}E[p]; int Et,hs[p];
	inline void Clear(){Et=0,memset(hs,-1,sizeof(hs));}
	inline void Insert(int w,int x){E[++Et]=(node){x,w,hs[w%p]},hs[w%p]=Et;}
	inline signed locate(int W){
		for (rr int i=hs[W%p];~i;i=E[i].next)
		    if (E[i].w==W) return E[i].y;
		return -1;
	}
}ha;
inline lll gcd(lll x,lll y){return y?gcd(y,x%y):x;}
inline lll exBSGS(lll a,lll c,lll b,lll mod){
	ha.Clear();
	rr lll GCD=gcd(a,mod),t=1;
	rr lll CNT=0,ir=sqrt(mod)+1;
	while (GCD>1){
		if (b%GCD||c%GCD) return -1;
		b/=GCD,c/=GCD,mod/=GCD,
		t=t*(a/GCD)%mod,
		GCD=gcd(a,mod),++CNT;
		if (b==t*c%mod) return CNT;
	}
	rr lll now=1;
	for (rr int i=0;i<ir;++i)
	    ha.Insert(now*b%mod,i),now=now*a%mod;
	a=now,now=t;
	if (!a) return !b?1:-1;
	for (rr int i=0;i<=ir;++i){
		rr int j=ha.locate(now*c%mod);
		if (j>=0&&i*ir+CNT>j) return i*ir+CNT-j;
		now=now*a%mod;
	}
	return -1;
}
inline lll ksm(lll x,lll y){
	rr lll ans=1;
	for (;y;y>>=1,x=x*x%mod)
	    if (y&1) ans=ans*x%mod;
	return ans; 
}
signed main(){
	scanf("%s%s%s%s%lld",A+1,B+1,C+1,G+1,&mod);
	lA=strlen(A+1),lB=strlen(B+1),lC=strlen(C+1),lG=strlen(G+1);
	for (rr int i=1;i<=lG;++i) g=(g*10+G[i]-48)%mod;
	for (rr int i=1;i<=lC;++i) c=(c*10+C[i]-48)%mod;
	for (rr int i=1;i<=lA;++i) a=(a*10+A[i]-48)%(mod-1);
	for (rr int i=1;i<=lB;++i) b=(b*10+B[i]-48)%(mod-1);
	a=ksm(g,a),b=ksm(g,b),ans=exBSGS(a,b,c,mod);
	if (ans==-1) printf("no solution");
	    else printf("%lld",ans);
	return 0;
}

标签:BSGS,return,GCD,rr,int,lll,3285,mod,BZOJ
来源: https://www.cnblogs.com/Spare-No-Effort/p/15333313.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有