• Pollard-Rho


    Miller-Rabin

    大素数测试

    Miller-Rabin算法本质上是一种概率算法,存在误判的可能性,但是出错的概率非常小。出错的概率到底是多少,存在严格的理论推导。

    费马小定理

    (p) 是素数, (gcd(a,p) = 1) , 那么 (a^{p-1} = 1 (mod p))

    如果存在 $a < p $ , 且 (a^{p-1} \% p e 1) , 则 (p) 肯定不是素数

    有限域上的平方根定理

    如果 (p) 是一个奇素数且 (e ge 1) ,则

    [x^2 = 1 (mod p^e) ]

    仅有两个根 (x = 1)(x = -1) , 注意到在模 (p) 的意义下 (x = -1) 等价于 (x = p - 1) , 正负一 也被称为 (1) 的平凡平方根

    如果对模 (n) 存在 (1) 的非平凡平方根, (n) 一定是合数

    ...

    没有很懂

    抄了个板子,A 了 19徐州那道题

    E- Multiply

    但是只过了洛谷的板子的两个点

    【模板】Pollard-Rho

    还顺带把 CCPC威海的 D 题给 AC了

    (判断有没有一个质因数的次数大于等于2)

    signed main(){
        scanf("%lld",&T);
        while(T--){
            ans = 0;
            scanf("%lld",&n);m.clear();
            find(n);
            if(ans)puts("yes");
            else puts("no");
            
        }
    }
    

    这个板子用着应该是没啥问题

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N = 1e5 + 5;
    
    int x[105];
    int mul(int a, int b, int p){
    	int ans = 0;
    	while (b){
    		if (b & 1LL) ans = (ans + a) % p;
    		a = (a + a) % p;
    		b >>= 1;
    	}
    	return ans;
    }
    
    int qpow(int a, int b, int p){
    	int ans = 1;
    	while (b){
    		if (b & 1LL) ans = mul(ans, a, p);
    		a = mul(a, a, p);
    		b >>= 1;
    	}
    	return ans;
    }
    
    bool Miller_Rabin(int n){ //大素数测试
    	if (n == 2) return true;
    	int s = 20, i, t = 0;
    	int u = n - 1;
    	while (!(u & 1))
    	{
    		t++;
    		u >>= 1;
    	}
    	while (s--)
    	{
    		int a = rand() % (n - 2) + 2;
    		x[0] = qpow(a, u, n);
    		for (i = 1; i <= t; i++)
    		{
    			x[i] = mul(x[i - 1], x[i - 1], n);
    			if (x[i] == 1 && x[i - 1] != 1 && x[i - 1] != n - 1)
    				return false;
    		}
    		if (x[t] != 1) return false;
    	}
    	return true;
    }
    
    int gcd(int a, int b){
    	return b ? gcd(b, a % b) : a;
    }
    
    int Pollard_Rho(int n, int c){
    	int i = 1, k = 2, x = rand() % (n - 1) + 1, y = x;
    	while (1){
    		i++;
    		x = (mul(x, x, n) + c) % n;
    		int p = gcd((y - x + n) % n, n);
    		if (p != 1 && p != n) return p;
    		if (y == x) return n;
    		if (i == k){
    			y = x;
    			k <<= 1;
    		}
    	}
    }
    
    map<int, int> m;
    void find(int n, int c = 12345)
    {
    	if (n == 1) return;
    	if (Miller_Rabin(n)){
    		m[n]++;
    		return;
    	}
    	int p = n, k = c;
    	while (p >= n) p = Pollard_Rho(p, c--);
    	find(p, k);
    	find(n / p, k);
    }
    

    E - Multiply

    直接上板子

    int T, n, X, Y, A[100010];
    
    int cal(int n, int p) {
    	int ans = 0;
    	while (n) {
    		ans += n / p;
    		n /= p;
    	}
    	return ans;
    }
    
    map<int, int>mp;
    signed main() {
    	scanf("%lld", &T);
    	while (T--) {
    		scanf("%lld%lld%lld", &n, &X, &Y);
    		for (int i = 1; i <= n; i++)scanf("%lld", A + i);
    		m.clear(); mp.clear();
    		find(X);
    
    		for (auto& i : m) {
    			mp[i.first] += cal(Y, i.first);
    		}
    		for (auto& i : m) {
    			for (int j = 1; j <= n; j++) {
    				mp[i.first] -= cal(A[j], i.first);
    			}
    		}
    		int ans = 1e18;
    
    		for (auto& i : m) {
    			ans = min(ans, mp[i.first] / i.second);
    		}
    		printf("%lld
    ", ans);
    
    	}
    }
    
    
    
  • 相关阅读:
    poj 1562 Oil Deposits
    poj 1650 Integer Approximation
    snmp4j 编程
    ubuntu 13.04 163源(亲测可用)
    c语言中static 用法总结(转)
    Spring入门
    Hibernate入门
    Struts2入门教程
    素数距离问题
    ASCII码排序
  • 原文地址:https://www.cnblogs.com/sduwh/p/13925242.html
Copyright © 2020-2023  润新知