zoukankan      html  css  js  c++  java
  • 2021.3.24

    (mathcal{A})
    bsgs别忘了等式右边b=0和同n不互质的情况。
    (mathcal{B})

    数论之神

    #include <bits/stdc++.h>
    using namespace std;
    namespace cxcyl {
    	typedef long long ll;
    	const int inf = (int)1e9;
    	struct Hashmap {
    		static const int key = 999917, N = (int)5e5 + 5;
    		int fir[key], x[N], y[N], nxt[N], cnt, stk[N], top;
    		inline Hashmap() {}
    		inline void clear() { cnt = 0; while (top) fir[stk[top--]] = 0; }
    		inline void add(int a, int b) { x[++cnt] = b; y[cnt] = inf; nxt[cnt] = fir[a]; fir[a] = cnt; }
    		inline int count(int idx) {
    			int u = idx % key;
    			for (int e = fir[u]; e; e = nxt[e])
    				if (x[e] == idx)
    					return 1;
    			return 0;
    		}
    		inline int &operator [](int idx) {
    			int u = idx % key;
    			for (int e = fir[u]; e; e = nxt[e])
    				if (x[e] == idx)
    					return y[e];
    			add(u, idx), stk[++top] = u; return y[cnt];
    		}
    	} s;
    	int fac[100][2], cnt;
    	int gcd(int x, int y) { return y == 0 ? x : gcd(y, x % y); }
    	inline int fpow_r(int a, int b) {
    		int ret = 1;
    		for (; b; b >>= 1, a = a * a)
    			if (b & 1)
    				ret = ret * a;
    		return ret;
    	}
    	inline int fpow(int a, int b, int mod) {
    		int ret = 1;
    		for (; b; b >>= 1, a = 1ll * a * a % mod)
    			if (b & 1)
    				ret = 1ll * ret * a % mod;
    		return ret;
    	}
    	inline int phi(int n) {
    		int m = n;
    		for (int i = 2; i * i <= n; ++i)
    			if (n % i == 0) {
    				while (n % i == 0) n /= i;
    				m -= m / i;
    			}
    		if (n > 1) m -= m / n;
    		return m;
    	}
    	inline int gen(int p) {
    		int x = phi(p);
    		for (int i = 2; ; ++i) {
    			bool flag = 1;
    			for (int j = 2; j * j < x && flag; ++j)
    				if (x % j == 0) {
    					if (fpow(i, j, p) == 1) flag = 0;
    					if (fpow(i, x / j, p) == 1) flag = 0;
    				}
    			if (flag) return i;
    		}
    	}					
    	inline void getfac(int n) {
    		for (int i = 2; i * i <= n; ++i)
    			if (n % i == 0) {
    				fac[++cnt][0] = i;
    				while (n % i == 0) n /= i, ++fac[cnt][1];
    			}
    		if (n > 1) {
    			fac[++cnt][0] = n;
    			fac[cnt][1] = 1;
    		}
    	}
    	inline int bsgs(int a, int b, int c) {
    		assert(gcd(a, c) == 1);
    		s.clear();
    		int n = ceil(sqrt(c)), x = 1, ret = 1e9, o = phi(c);
    		for (int i = 0; i <= n; ++i) {
    			s[x] = min(s[x], i);
    			if (i < n) x = 1ll * x * a % c;
    		}
    		for (int i = 0, y = 1; i <= n; ++i, y = 1ll * y * x % c) {
    			int t = 1ll * b * fpow(y, o - 1, c) % c;
    			if (s.count(t)) ret = min(ret, s[t] + i * n);
    		}
    		return ret < 1e9 ? ret : -1;
    	}
    	inline ll exgcd(ll a, ll b, ll &x, ll &y) {
    		if (b == 0) { x = 1; y = 0; return a; }
    		ll ret = exgcd(b, a % b, y, x);
    		y -= a / b * x;
    		return ret;
    	}
    	inline int main() {
    		int T;
    		scanf("%d", &T);
    		while (T--) {
    			cnt = 0;
    			memset(fac, 0, sizeof(fac));
    			//clear
    			int A, B, k;
    			scanf("%d%d%d", &A, &B, &k);
    			getfac(2 * k + 1);
    			int ans = 1;
    			for (int i = 1; i <= cnt; ++i) {
    				int u = fpow_r(fac[i][0], fac[i][1]), g = gen(u), a = A, b = B;
    				if (b % u == 0)
    					ans = ans * fpow_r(fac[i][0], fac[i][1] - ceil((double)fac[i][1] / a));
    				else {
    					int d = gcd(b, u);
    					if (d > 1) {
    						b /= d;
    						u /= d;
    						int cnt = 0;
    						while (d > 1) {
    							d /= fac[i][0];
    							++cnt;
    						}
    						if (cnt % a) ans = 0;
    						else ans = ans * fpow_r(fac[i][0], cnt - cnt / a);
    					}
    					int b0 = bsgs(g, b, u), o = phi(u);
    					ll x, y, l = exgcd(a, o, x, y);
    					if (b0 % l) ans = 0;
    					else {
    						ll r = o / l;
    						x = (x * b0 / l % r + r) % r;
    						ans = ans * ((o - 1 - x) / r + 1);
    					}
    				}
    			}
    			printf("%d
    ", ans);
    		}
    		return 0;
    	}
    } int main() { return cxcyl::main(); }
    

    Fib数列


    由通项列方程:(t - frac{1}{t} equiv sqrt{5}N(mod p), t = (frac{sqrt{5}+1}{2})^{n}),用求根公式用几次二次剩余求解。

    #include <bits/stdc++.h>
    using namespace std;
    namespace cxcyl {
    	const int inf = (int)1e9, mod = (int)1e9 + 9, inv2 = mod + 1 >> 1;
    	int N, ans[2] = {inf, inf}, s5;
    	struct Com {
    		static int sqr;
    		int re, im;
    		inline Com(int x = 0, int y = 0) : re(x), im(y) {}
    		inline Com operator *(const Com &rhs) {
    			return Com((1ll * re * rhs.re + 1ll * im * rhs.im % mod * sqr) % mod, (1ll * re * rhs.im + 1ll * im * rhs.re) % mod);
    		}
    	};
    	int Com::sqr;
    	template<typename T> inline int chkmin(T &x, T y) { return x > y ? x = y, 1 : 0; }
    	inline int fpow(int a, int b) {
    		int ret = 1;
    		for (; b; b >>= 1, a = 1ll * a * a % mod)
    			if (b & 1)
    				ret = 1ll * ret * a % mod;
    		return ret;
    	}
    	inline Com fpow(Com a, int b) {
    		Com ret(1, 0);
    		for (; b; b >>= 1, a = a * a)
    			if (b & 1)
    				ret = ret * a;
    		return ret;
    	}
    	inline int mod_sqrt(int x) {
    		if (fpow(x, mod - 1 >> 1) != 1) return -1;
    		int a = rand();
    		while (fpow(((1ll * a * a - x) % mod + mod) % mod, mod - 1 >> 1) == 1) a = rand();
    		Com::sqr = ((1ll * a * a - x) % mod + mod) % mod;
    		return (fpow(Com(a, 1), mod + 1 >> 1).re + mod) % mod;
    	}
    	inline pair<int, int> bsgs(int a, int b, int c) {
    		map<int, int> s[2];
    		int n = ceil(sqrt(c)), x = 1, ret[2] = {inf, inf};
    		for (int i = 0; i <= n; ++i) {
    			if (s[i & 1].find(x) == s[i & 1].end() || s[i & 1][x] > i) s[i & 1][x] = i;
    			if (i < n) x = 1ll * x * a % c;
    		}
    		for (int i = 0, y = 1; i <= n; ++i, y = 1ll * y * x % c) {
    			int t = 1ll * b * fpow(y, c - 2) % c;
    			if (s[0].find(t) != s[0].end()) chkmin(ret[(i * n + s[0][t]) & 1], i * n + s[0][t]);
    			if (s[1].find(t) != s[1].end()) chkmin(ret[(i * n + s[1][t]) & 1], i * n + s[1][t]);
    		}
    		return make_pair(ret[0], ret[1]);
    	}
    	inline void work(int you, int d) {
    		you = (you + mod) % mod;
    		pair<int, int> ret = bsgs((1ll + s5) * inv2 % mod, you, mod);
    		if (d == 0) ans[0] = min(ans[0], ret.first);
    		else ans[1] = min(ans[1], ret.second);
    	}
    	inline int main() {
    		scanf("%d", &N);
    		s5 = mod_sqrt(5);
    		int tmp0 = (5ll * N * N - 4) % mod, tmp1 = (5ll * N * N + 4) % mod;
    		int ret = mod_sqrt(tmp0);
    		if (ret != -1) {
    			work((1ll * s5 * N + ret) % mod * inv2 % mod, 1);
    			work((1ll * s5 * N - ret) % mod * inv2 % mod, 1);
    		}
    		ret = mod_sqrt(tmp1);
    		if (ret != -1) {
    			work((1ll * s5 * N + ret) % mod * inv2 % mod, 0);
    			work((1ll * s5 * N - ret) % mod * inv2 % mod, 0);
    		}
    		if (ans[0] == 1e9 && ans[1] == 1e9) puts("-1");
    		else printf("%d
    ", min(ans[0], ans[1]));
    		return 0;
    	}
    } int main() { return cxcyl::main(); }
    
  • 相关阅读:
    HTML基础
    一次由任意文件漏洞开始的渗透测试过程
    谈一谈信息泄露这件事
    浅谈任意文件下载漏洞的利用
    [原创] 一次渗透测试过程--从外网进内网
    一次绕过360+诺顿的提权过程
    漏洞挖掘高级方法
    新型勒索软件Magniber正瞄准韩国、亚太地区开展攻击
    Microsoft Edge 浏览器远程代码执行漏洞POC及细节(CVE-2017-8641)
    Office远程代码执行漏洞CVE-2017-0199复现
  • 原文地址:https://www.cnblogs.com/herald/p/14572804.html
Copyright © 2011-2022 走看看