zoukankan      html  css  js  c++  java
  • PKU 2429 GCD & LCM Inverse

    大数分解pollard-rho

    素数判定miller-rabin

    #include<stdio.h>
    #include<time.h>
    #include<stdlib.h>
    #define LL unsigned long long
    #define nmax 2005
    LL factor[nmax], num[nmax], minx, ans;
    int flen, nnum;
    LL modular_multi(LL a, LL b, LL c) {
    	LL ret;
    	ret = 0, a %= c;
    	while (b) {
    		if (b & 1) {
    			ret += a;
    			if (ret >= c) {
    				ret -= c;
    			}
    		}
    		a <<= 1;
    		if (a >= c) {
    			a -= c;
    		}
    		b >>= 1;
    	}
    	return ret;
    }
    LL modular_exp(LL a, LL b, LL c) {
    	LL ret;
    	ret = 1, a %= c;
    	while (b) {
    		if (b & 1) {
    			ret = modular_multi(ret, a, c);
    		}
    		a = modular_multi(a, a, c);
    		b >>= 1;
    	}
    	return ret;
    }
    int miller_rabin(LL n, int times) {
    	if (n == 2) {
    		return 1;
    	}
    	if ((n < 2) || (!(n & 1))) {
    		return 0;
    	}
    	LL temp, a, x, y;
    	int te, i, j;
    	temp = n - 1;
    	te = 0;
    	while (!(temp & 1)) {
    		temp >>= 1;
    		te++;
    	}
    	srand(time(0));
    	for (i = 0; i < times; i++) {
    		a = rand() % (n - 1) + 1;
    		x = modular_exp(a, temp, n);
    		for (j = 0; j < te; j++) {
    			y = modular_multi(x, x, n);
    			if ((y == 1) && (x != 1) && (x != (n - 1))) {
    				return 0;
    			}
    			x = y;
    		}
    		if (x != 1) {
    			return 0;
    		}
    	}
    	return 1;
    }
    LL gcd(LL a, LL b) {
    	LL te;
    	if (a < b) {
    		te = a, a = b, b = te;
    	}
    	if (b == 0) {
    		return a;
    	}
    	while (b) {
    		te = a % b, a = b, b = te;
    	}
    	return a;
    }
    LL pollard_rho(LL n, int c) {
    	LL x, y, d, i, k;
    	srand(time(0));
    	x = rand() % (n - 1) + 1;
    	y = x;
    	i = 1;
    	k = 2;
    	while (1) {
    		i++;
    		x = (modular_multi(x, x, n) + c) % n;
    		d = gcd(y - x, n);
    		if ((d > 1) && (d < n)) {
    			return d;
    		}
    		if (y == x) {
    			return n;
    		}
    		if (i == k) {
    			y = x;
    			k <<= 1;
    		}
    	}
    	return -1;
    }
    void findFactor(LL n, int c) {
    	if (n == 1) {
    		return;
    	}
    	if (miller_rabin(n, 6)) {
    		factor[++flen] = n;
    		return;
    	}
    	LL p = n;
    	while (p >= n) {
    		p = pollard_rho(p, c--);
    	}
    	findFactor(p, c);
    	findFactor(n / p, c);
    
    }
    int cmp(const void *a, const void *b) {
    	LL te = (*(LL *) a - *(LL *) b);
    	if (te > 0) {
    		return 1;
    	} else if (te < 0) {
    		return -1;
    	}
    	return 0;
    }
    void solve() {
    	qsort(factor, flen + 1, sizeof(factor[0]), cmp);
    	num[0] = factor[0];
    	nnum = 0;
    	int i;
    	for (i = 0; i < flen; i++) {
    		if (factor[i] == factor[i + 1]) {
    			num[nnum] *= factor[i + 1];
    		} else {
    			num[++nnum] = factor[i + 1];
    		}
    	}
    }
    void dfs(int s, LL sn, LL n) {
    	if (s == nnum + 1) {
    		if (minx == -1 || (sn + n / sn < minx)) {
    			if (gcd(sn, n / sn) == 1) {
    				minx = sn + n / sn;
    				ans = sn;
    			}
    		}
    		return;
    	}
    	dfs(s + 1, sn * num[s], n);
    	dfs(s + 1, sn, n);
    }
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("t.txt", "r", stdin);
    #endif
    	LL a, b, n, x, y;
    	while (scanf("%lld %lld", &a, &b) != EOF) {
    		if (a == b) {
    			printf("%lld %lld\n", a, b);
    			continue;
    		}
    		n = b / a;
    		if (miller_rabin(n, 10)) {
    			printf("%lld %lld\n", a, b);
    			continue;
    		}
    		flen = -1;
    		findFactor(n, 207);
    		solve();
    		minx = -1LL;
    		dfs(0, 1LL, n);
    		x = ans;
    		y = n / ans;
    		if (x > y) {
    			n = x, x = y, y = n;
    		}
    		printf("%lld %lld\n", x * a, y * a);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    [原创]Java在线编辑word文档调用PageOffice实现并发控制
    [原创]Java动态填充word文档并上传到服务器
    mysql数据类型
    mysql 数据增删改查基本语句
    MYSQL中char 与 varchar 的区别
    MYSQL 同时执行多条SQL语句
    关于MyEclipse10编辑JSP卡顿现象
    鼠标悬停放大图片效果
    简单实现 飘浮 广告层特效
    简单实现 特效(董侨JonneyDong)
  • 原文地址:https://www.cnblogs.com/xiaoxian1369/p/2123970.html
Copyright © 2011-2022 走看看