【POJ】3243 Clever Y

http://poj.org/problem?id=3243

题意:求$a^y \equiv b \pmod{p}$最小的$y$。(0<=x, y, p<=10^9)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
typedef long long ll;
using namespace std;
int gcd(int a, int b) { return b?gcd(b, a%b):a; }
void exgcd(ll a, ll b, ll &d, ll &x, ll &y) { if(!b) { d=a; x=1; y=0; return; } exgcd(b, a%b, d, y, x); y-=a/b*x; }
int ni(int a, int b) {
	static ll x, y, d;
	exgcd(a, b, d, x, y);
	return (x+b)%b;
}
int ipow(int a, int b, int c) { int x=1; for(; b; b>>=1, a=(ll)a*a%c) if(b&1) x=(ll)x*a%c; return x; }
struct H {
	static const int md=3999997;
	bool vis[md]; int dt[md], foo[md], s[md], top;
	void clr() { while(top) { int x=s[top--]; vis[x]=0, dt[x]=-1; } }
	void add(int a, int b) {
		int x=a%md;
		while(1) { if(!vis[x] || dt[x]==a) { if(!vis[x]) s[++top]=x; vis[x]=1; dt[x]=a; foo[x]=b; break; } ++x; if(x==md) x=0; }
	}
	int find(int a) {
		int x=a%md;
		while(1) { if(!vis[x]) return -1; if(dt[x]==a) return foo[x]; ++x; if(x==md) x=0; }
	}
}h;
int a, b, mo;
bool spj() {
	if(b==1) puts("0");
	else if(!a && !b) puts("1");
	else if(!b) puts("No Solution");
	else return 0;
	return 1;
}
void work() {
	b%=mo;
	if(spj()) return;
	for(int i=0, t=1; i<30; ++i, t=(ll)t*a%mo) if(t==b) { printf("%d\n", i); return; }
	int a1=0, d=1, g;
	while((g=gcd(a, mo))!=1) { if(b%g) { puts("No Solution"); return; } ++a1, mo/=g, b/=g, d=(ll)a/g*d%mo; }
	d=ni(d, mo);
	int m=sqrt(0.5+mo);
	h.clr();
	for(int i=0, t=(ll)b*d%mo; i<m; ++i, t=(ll)t*a%mo) h.add(t, i);
	for(int i=0, wn=ipow(a, m, mo), t=1; i<=m; ++i, t=(ll)t*wn%mo) { int x=h.find(t); if(x!=-1) { printf("%d\n", a1+i*m-x); return; } }
	puts("No Solution");
}
int main() {
	while(scanf("%d%d%d", &a, &mo, &b) && (a|b|mo)) work();
	return 0;
}

  

拓展的大步小步= =

跪跪跪:http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4

由于$c$不一定是质数,因此不能用原来的bsgs算法

而这样的话有解但是可能不唯一。

但是还是容易想到枚举$i$解出这个方程$a^{im} x \equiv b \pmod{p}$ 然后查找$x$是否为$a^t$,然后答案就是$im+t$。

可是发现这样的解集大小为$(a^{im}, p)$,有可能很大= =无法承受....

我们来通过将方程变成一种等价形式来简化问题:

我们将式子同时除以$d=(a, p)$,得到:$\frac{a}{d} a^m \equiv \frac{b}{d} \pmod{\frac{p}{d}}$。(当然如果$b$不能整除$d$那么方程无解辣= =将$b = xxx$搞一下就可以知道辣= =)

一直进行了$t$次直到$(a, p_{t}) = 1$,令$D = a^t \frac{1}{\prod_{i=1}^{t}} d_{t}$,那么显然$(D, p_{t}) = 1$是不是辣= =

那么得到原方程的等价形式$a^h \equiv b_{t} D^{-1} \pmod{p_t}$,解出$h$那么原问题答案就是$h+t$辣= =

那么裸$bsgs$辣

可是这里要注意哦,可能存在$y<t$的情况哟,由于$t$松的上界为$log_2 p$,我们先枚举一下判断就行辣....

时间: 2024-10-07 18:45:18

【POJ】3243 Clever Y的相关文章

【数论】【ex-BSGS】poj3243 Clever Y

用于求解高次同余方程A^x≡B(mod C),其中C不一定是素数. http://blog.csdn.net/tsaid/article/details/7354716 这篇题解写得最好. 那啥,这题的坑点请去看discuss. #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; vo

【BZOJ1467/2480】Pku3243 clever Y/Spoj3105 Mod EXBSGS

[BZOJ1467/2480]Pku3243 clever Y/Spoj3105 Mod Description 已知数a,p,b,求满足a^x≡b(mod p)的最小自然数x. Input 每个测试文件中最多包含100组测试数据. 每组数据中,每行包含3个正整数a,p,b. 当a=p=b=0时,表示测试数据读入完全. Output 对于每组数据,输出一行. 如果无解,输出“No Solution”(不含引号),否则输出最小自然数解. Sample Input 5 58 33 2 4 3 0 0

poj 3243 Clever Y 高次方程

1 Accepted 8508K 579MS C++ 2237B/** 2 hash的强大,,还是高次方程,不过要求n不一定是素数 3 **/ 4 #include <iostream> 5 #include <cstdio> 6 #include <cmath> 7 #include <cstring> 8 #include <algorithm> 9 using namespace std; 10 long long a,b,n; 11 co

【POJ】2318 TOYS ——计算几何+二分

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10281   Accepted: 4924 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

【POJ】3009 Curling 2.0 ——DFS

Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11432   Accepted: 4831 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is

【POJ】3207 Ikki&#39;s Story IV - Panda&#39;s Trick

http://poj.org/problem?id=3207 题意:一个圆上顺时针依次排列着标号为1-n的点,这些点之间共有m条边相连,每两个点只能在圆内或者圆外连边.问是否存在这些边不相交的方案.(n<=1000, m<=500) #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <iostream> using n

【POJ】1228 Grandpa&#39;s Estate(凸包)

http://poj.org/problem?id=1228 随便看看就能发现,凸包上的每条边必须满足,有相邻的边和它斜率相同(即共线或凸包上每个点必须一定在三点共线上) 然后愉快敲完凸包+斜率判定,交上去wa了QAQ.原因是忘记特判一个地方....因为我们求的凸包是三点共线的凸包,在凸包算法中我们叉积判断只是>0而不是>=0,那么会有一种数据为所有点共线的情况,此时求出来的凸包上的点是>原来的点的(此时恰好符合答案NO,因为可以在这条线外随便点一个点就是一个凸包了...)然后特判一下.

【POJ】2492 A bug&#39;s life ——种类并查集

A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28211   Accepted: 9177 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders

【POJ】 Instant Complexity (模拟)

[POJ] Instant Complexity (模拟) Instant Complexity Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 1905   Accepted: 657 Description Analyzing the run-time complexity of algorithms is an important tool for designing efficient programs that