zoukankan      html  css  js  c++  java
  • 【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
    ", 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
    ", 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$,我们先枚举一下判断就行辣....

  • 相关阅读:
    ubuntu 下python安装及hello world
    mongodb数据库学习【安装及简单增删改查】
    samba服务器共享开发【windows下开发linux网站】
    系统架构一:snmp+mrtg服务器监控
    记.gitignore的一次惊心动魄
    第一章 引论 第二章 算法分析
    渗透测试实践指南(1)
    day7
    day5 io模型
    day4(带)
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4374178.html
Copyright © 2011-2022 走看看