zoukankan      html  css  js  c++  java
  • ICPC2019 Xuzhou E. Multiply Pollard_Rho 大数分解

    ICPC2019 Xuzhou E. Multiply Pollard_Rho 大数分解

    题意

    给出(n)个数(a_i),令(Z = prod a_i!)

    给出(X,Y),令(b_i = Z imes X^i) ,它想要一个最大的(i),使得(b_i | Y!)

    [N leq 10^5\ X,Y leq10^{18}\ a_i leq 10^{18} ]

    分析

    考虑到(X)的值没有阶乘,相对较小,应该从他来做文章

    对要求的式子做变换,得到(X^i | frac{Y!}{Z})

    由于(X^i),(X)的质因子不会受到(i)的影响,因此它的质因子不会很大

    考虑使用(Pollard\_Rho)算法来分解(X),期望复杂度(O(X^{frac{1}{4}}))

    这样只要对每个质因子贪心地拼凑出来满足小于等于(frac{Y!}{Z})的即可,后者对应的质因子的指数可以通过简单的trick来完成

    考虑一个阶乘(n!)的质因子(d)的出现次数

    [n! = (d imes 2d imes 3d...lfloorfrac{n}{d} floor d) imes a\ = d^{lfloorfrac{n}{d} floor} imes lfloorfrac{n}{d} floor! imes a\ = ... ]

    于是可以用一个while循环来搞定

    此处直接使用kuangbin的模板

    代码

    #include<bits/stdc++.h>
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define re register
    using namespace std;
    typedef long long ll;
    
    ll rd(){
    	ll x = 0;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9') {
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return x;
    }
    
    const int maxn = 200;
    ll factor[maxn];
    int tol;
    const int S  = 8;
    
    inline ll mult_mod(ll a,ll b,ll c){
    	a %= c;
    	b %= c;
    	ll ret = 0;
    	ll tmp = a;
    	while(b){
    		if(b & 1) {
    			ret += tmp;
    			if(ret > c) ret -= c;
    		}
    		tmp <<= 1;
    		if(tmp > c) tmp -= c;
    		b >>= 1;
    	}
    	return ret;
    }
    
    inline ll pow_mod(ll a,ll n,ll mod){
    	ll ret = 1;
    	ll tmp = a % mod;
    	while(n){
    		if(n & 1) ret = mult_mod(ret,tmp,mod);
    		tmp = mult_mod(tmp,tmp,mod);
    		n >>= 1;
    	}
    	return ret;
    }
    
    inline bool check(ll a,ll n,ll x,ll t){
    	ll ret = pow_mod(a,x,n);
    	ll last = ret;
    	for(int i = 1;i <= t;i++){
    		ret = mult_mod(ret,ret,n);
    		if(ret == 1 && last != 1 && last != n - 1) return true;
    		last = ret;
    	}
    	if(ret != 1) return true;
    	else return false;
    }
    
    inline bool Miller_Rabin(ll n){
    	if(n < 2) return false;
    	if(n == 2) return true;
    	if((n & 1) == 0) return false;
    	ll x = n - 1;
    	ll t = 0;
    	while((x & 1) == 0) {
    		x >>= 1;
    		t++;
    	}
    	srand(time(NULL));
    	for(int i = 0;i < S;i++){
    		ll a = rand() % (n - 1) + 1;
    		if(check(a,n,x,t)) return false;
    	}
    	return true;
    }
    
    
    inline ll gcd(ll a,ll b){
    	ll t;
    	while(b){
    		t = a;
    		a = b;
    		b = t % b;
    	}
    	if(a >= 0) return a;
    	else return -a;
    }
    
    inline ll pollard_rho(ll x,ll c){
    	ll i = 1,k = 2;
    	srand(time(NULL));
    	ll x0 = rand() % (x - 1) + 1;
    	ll y = x0;
    	while(1) {
    		i++;
    		x0 = (mult_mod(x0,x0,x) + c) % x;
    		ll d = gcd(y - x0,x);
    		if(d != 1 && d != x) return d;
    		if(y == x0) return x;
    		if(i == k) {
    			y = x0;
    			k += k;
    		}
    	}
    }
    
    void findfac(ll n,int k){
    	if(n == 1) return;
    	if(Miller_Rabin(n)) {
    		factor[tol++] = n;
    		return;
    	}
    	ll p = n;
    	int c = k;
    	while(p >= n) p = pollard_rho(p,c--);
    	findfac(p,k);
    	findfac(n / p,k);
    }
    
    inline ll get(ll x,ll p){
    	ll cnt = 0;
    	while(x){
    		cnt += x / p;
    		x /= p;
    	}
    	return cnt;
    }
    
    int main(){
    	int T = rd();
    	while(T--){
    		tol = 0;
    		memset(factor,0,sizeof factor);
    		int n = rd();
    		ll x = rd();
    		ll y = rd();
    		vector<ll> v(n);
    		for(int i = 0;i < n;i++)
    			v[i] = rd();
    		findfac(x,107);
    		map<ll,ll> mp;
    		for(int i = 0;i < tol;i++){
    			mp[factor[i]]++;	
    		}	
    		ll ans = 4e18;
    		for(auto it:mp){
    			ll cnt = 0;
    			for(auto itt:v)
    				cnt += get(itt,it.fi);
    			ans = min(ans,(get(y,it.fi) - cnt) / it.se);
    		}
    		printf("%lld
    ",ans);
    	}
    }
    
  • 相关阅读:
    Qt QCustomPlot 取数据,鼠标移动显示
    [Leetcode]Swap Nodes in Pairs
    [Leetcode]Sort Colors
    [Leetcode]Unique Paths
    [Leetcode]Find Minimum in Rotated Sorted Array
    [Leetcode]Merge Two Sorted Lists
    [Leetcode]Convert Sorted Array to Binary Search Tree
    [Leetcode]Unique Paths
    [Leetcode]Climbing Stairs
    [Leetcode]Remove Duplicates from Sorted List
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14751476.html
Copyright © 2011-2022 走看看