zoukankan      html  css  js  c++  java
  • xgzc— math 专题训练(二)

    费马小定理&欧拉定理

    费马小定理:
    如果(p)是一个质数,而整数(a)不是(p)的倍数,(a^{p-1}equiv1pmod p)
    欧拉定理:
    (a)(n)互质时,(a^b equiv a^{b\%phi(n)} pmod n)
    扩展欧拉定理:

    [a^b equiv egin{cases} a^bpmod n (b<phi(n))\ a^{b\%phi(n)+phi(n)pmod n (bgephi(n))}\ end{cases} ]

    BSGS

    求方程(a^xequiv bpmod p)((a)(p)互质)的解
    (m=lceil sqrt p ceil),设(x = m*i-j)
    那么易知,((a^m)^iequiv b*a^jpmod p)
    我们可以把右边的全部丢到(map)里,然后枚举左边的,看看(map)中有没有

    
    map<int, int> M;
    int BSGS(int a, int b, int p) {
    	if (b == 1 && a) return 0;
    	M.clear(); int m = ceil(sqrt(p));
    	LL t = 1;
    	for (int i = 0; i < m; i++, t = t * a % p) M[t * b % p] = i;
    	for (int i = 1, s = t; i <= m + 1; i++, s = t * s % p) {
    		map<int, int> :: iterator it = M.find(s);
    		if (it == M.end()) continue;
    		return m * i - (it->second);
    	}
    	return -1;
    }
    int main() {
    	int a, b, p;
    	while (scanf("%d%d%d", &p, &a, &b) != EOF) {
    		int ans = BSGS(a, b, p);
    		if (ans == -1) puts("no solution");
    		else printf("%d
    ", ans);	
    	}
    	return 0;
    }
    

    EXBSGS

    (a)(p)不互质时,就不能除过去。
    考虑,(a^x=p*z+b)
    我们取(d = gcd(a,p))
    如果(b)不是(d)的倍数显然无解
    然后整体除(d)得到(frac{a}{d}a^{x-1}=frac{p}{d}*z+frac{b}{d})
    显然可以递归处理。。
    记录一下系数
    然后最后回带一下即可。

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    const int Mod = 1e5 + 7;
    int gcd(int x, int y) {
    	return !y ? x : gcd(y, x % y);
    }
    struct Hash {
    	struct node {
    		int a, b, nxt;
    	} A[1000010];
    	int lst[Mod], tot;
    	void clear() { memset(lst, 0, sizeof(lst)); tot = 0; }
    	void add(int a, int b, int S) {
    		A[++tot] = (node) {a, b, lst[S]};
    		lst[S] = tot;
    	}
    	void insert(int a, int b) { add(a, b, a % Mod); }
    	int find(int x) {
    		for (int i = lst[x % Mod]; i; i = A[i].nxt)
    			if (A[i].a == x) return A[i].b;
    		return -1;
    	}
    } M;
    int exBSGS(int a, int b, int p) {
    	if (b == 1 && a) return 0;
    	int d, k = 0, s = 1;
    	while ((d = gcd(a, p)) > 1) {
    		if (b % d) { return -1; }
    		b /= d; p /= d; k++; s = 1ll * s * a / d % p;
    		if (s == b) { return k; }
    	}
    	M.clear(); int m = ceil(sqrt(p));
    	LL t = 1;
    	for (int i = 0; i < m; i++, t = t * a % p) M.insert(t * b % p, i);
    	s = t * s % p;
    	for (int i = 1; i <= m + 1; i++, s = t * s % p) {
    		int it = M.find(s); if (it == -1) continue;
            return m * i - it + k;
    	}
    	return -1;
    }
    int main() {
    	int a, b, p;
    	while (scanf("%d%d%d", &a, &p, &b) != EOF) {
    		if (!a && !b && !p) return 0;
    		int ans = exBSGS(a, b, p);
    		if (ans == -1) puts("No Solution");
    		else printf("%d
    ", ans);
    	}
    	return 0;	
    }
    

    exLucas

    二次剩余(Cipolla)

  • 相关阅读:
    nuget 命令行小技巧
    非静态类、方法、属性要实例化对象
    ViewData 和 ViewBag
    每日记载内容总结32
    每日记载内容总结31
    hibernate 学习知识总结
    spring mvc 页面编码和数据库编码 中文出现乱码
    java代码生成二维码以及解析二维码
    每日记载内容总结30
    换公司,重新开始
  • 原文地址:https://www.cnblogs.com/zzy2005/p/11523672.html
Copyright © 2011-2022 走看看