zoukankan      html  css  js  c++  java
  • BSGS/exBSGS

    BSGS

    (y^x = z(mod p)) [(p in prime)]

    (y^{(x+k)} = z imes y^k(mod p))
    然后预处理 (k = [1, sqrt p])
    BSGS 就是大块枚举 ((x+k)),就做完了。

    exBSGS

    (p otin prime)
    ((A, p) ot| B) (and) (B != 1) 则无解。
    (G = (A, p))
    使得 (A^{x-1}frac{A}{G} = frac{B}{G} (mod frac{p}{G}))
    (A^{x-1} = AB(mod frac{p}{G})
    递归即可。

    #include <bits/stdc++.h>
    const int mod = 233333;
    struct Hash_Table {
    	Hash_Table() { clear(); }
    	struct List { int id, val, nxt; } e[233333];
    	int head[mod], cnt = 0;
    	void add(int u, int v, int w) { e[++cnt] = {v, w, head[u]}; head[u] = cnt; }
    	void clear() { memset(head, 0, sizeof(head)); cnt = 0; }
    	void insert(int x, int i) { int k = x % mod; add(k, x, i); } // mp[x] = i
    	int query(int x) {
    		for (int i = head[x % mod]; i; i = e[i].nxt) if (e[i].id == x) return e[i].val;
    		return -1;
    	}
    } hash;
    int qpow(int x, int y, int mod) {
    	int result = 1;
    	while (y) {
    		if (y & 1) { result = 1ll * result * x % mod; }
    		x = 1ll * x * x % mod; y >>= 1;
    	}
    	return result;
    }
    void NoAnswer() { std::cout << "No Solution" << '
    '; return; }
    void exbsgs(int y, int z, int p) {
    	if (z == 1) { std::cout << 0 << '
    '; return; }
    	int k = 0, qwq = 1; hash.clear();
    	for (int g = std::__gcd(y, p); g != 1; g = std::__gcd(y, p)) {
    		if (z % g) { NoAnswer(); return; }
    		z /= g; p /= g; ++k;
    		qwq = 1ll * qwq * (y / g) % p;
    		if (qwq == z) { std::cout << k << '
    '; return; }
    	}
    	int t = sqrt(p) + 1, s = z, base = y;
    	hash.insert(s, 0);
    	for (int i = 1; i <= t; i++) { s = 1ll * s * base % p; hash.insert(s, i); }
    	base = qpow(y, t, p); s = qwq;
    	for (int i = 1; i <= t; i++) {
    		s = 1ll * s * base % p;
    		if (!~hash.query(s)) { continue; }
    		qwq = hash.query(s);
    		std::cout << i * t - qwq + k << '
    ';
    		return;
    	}
    	NoAnswer();
    }
    int main() {
    	std::ios::sync_with_stdio(false);
    	std::cin.tie(NULL);
    	int a, p, b;
    	while (std::cin >> a >> p >> b && a && b && p) { exbsgs(a, b, p); }
    	return 0;
    }
    
  • 相关阅读:
    linux上安装mysql
    linux 上nginx配置
    js人民币数字转大写
    pm2常用命令
    基于redis实现分布式锁
    Enterprise Architect 14破解版 安装包 安装教程
    一些有用的链接
    Linux安装Zookeeper
    根据朋友圈的网易云音乐分享找到人
    我的待做事项
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/13469458.html
Copyright © 2011-2022 走看看