CF 1033 D. Divisors
D. Divisors
http://codeforces.com/contest/1033/problem/D
题意:
给n个(n<=500)个数,($a_i <= 2 \times 10 ^ {18}$),每个数的因数个数在[3,5]内。$a = \prod\limits_{i=1}^na_i$,求a的因数个数。
分析:
首先有一个结论:一个数x的质因数分解后为:$x = p_1^{a_1}p_2^{a_2}...p_k^{a_k}$ 那么它的因数个数就是 $(a_1 + 1) \times (a_2 + 1) \times ... \times (a_k + 1)$。
于是这道题就可以求出每个质因数的个数,然后将指数+1相乘即可。
但是$a_i$太大了,无法直接求质因数。
因为每个数的因数个数在[3,5]范围内,所以根据上面的结论,可以知道每个数的质因数分解只有四种形式:$pq, p^2, p^3,p^4$。后三种直接二分就能算出其质因数,用map记录每个质因数的指数。
对于第一种,直接求质因数是不可能的了,考虑能否不求质因数,而计算答案。首先对于所有数二分,如果不能分成后三种,那么将其记录到b数组中。b中的一个数拆成第一种形式后,p和q,在map都没出现过,那么我们可以知道它的贡献就是(2*2)了(不考虑后面的)。如果p和q中有一个出现过了,我们必须要合并他们的幂。
如何合并幂:枚举b[i],枚举a数组中的所有数,求gcd,如果1<gcd<b[i],那么可以说明b[i]和a[j]分解后的都有gcd,(b[i]=pq,gcd=p或者q)。
对于剩下的数,每一个分解后的质数都是还未出现过,直接计算答案。
代码:
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<iostream> #include<cctype> #include<set> #include<vector> #include<queue> #include<map> #define fi(s) freopen(s,"r",stdin); #define fo(s) freopen(s,"w",stdout); using namespace std; typedef long long LL; inline LL read() { LL x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 505; const int mod = 998244353; const LL INF = 9e18; LL a , b , c ; map<LL,int> f; LL Sqrt(LL x,int k) { LL l = 1, r; // 虽然现在的l,r在int范围内,但是也要开longlong!!!!! if (k == 2) r = 1414213563; if (k == 3) r = 1259922; if (k == 4) r = 37607; while (l <= r) { LL mid = (l + r) >> 1; LL t = 1; for (int i=1; i<=k; ++i) t = 1ll * t * mid; if (t == x) return mid; else if (t > x) r = mid - 1; else l = mid + 1; } return -1; } LL gcd(LL a,LL b) { return b == 0 ? a : gcd(b, a % b); } int main() { int n = read(); for (int i=1; i<=n; ++i) a[i] = read(); for (int i=1; i<=n; ++i) { bool flag = 0; for (int k=4; k>=2; --k) { // 从大到小!!! LL p = Sqrt(a[i], k); if (p != -1) { f[p]+= k; flag = 1; break; } } if (!flag) b[i] = a[i]; } for (int i=1; i<=n; ++i) { if (!b[i]) continue; bool flag = 0; for (int j=1; j<=n; ++j) { if (i == j) continue; LL d = gcd(b[i], a[j]); if (d != 1 && d != b[i]) { flag = 1; f[d] ++; f[b[i] / d] ++; break; } } if (!flag) c[i] = b[i]; } LL ans = 1; for (int i=1; i<=n; ++i) { if (!c[i]) continue; LL cnt = 2; for (int j=1; j<=n; ++j) if (i != j && c[i] == c[j]) cnt ++, c[j] = 0; cnt = cnt * cnt % mod; ans = ans * cnt % mod; } map<LL,int> :: iterator it; for (it=f.begin(); it!=f.end(); it++) ans = (ans * (it->second + 1)) % mod; // for (auto p: f) ans = (ans * (p.second + 1)) % mod; cout << ans; fflush(stdout); return 0; }
- CF A. Xenia and Divisors
- CF 27E Number With The Given Amount Of Divisors
- CF 1033 C. Permutation Game
- CF-27E - Number With The Given Amount Of Divisors(枚举+dfs)
- CF 112D. Petya and Divisors 枚举(标记倍数最后出现位置)
- CF-27E - Number With The Given Amount Of Divisors(枚举+dfs)
- CF 665F Four Divisors 1e11内素数个数(模板)
- D. Common Divisors CF 182D
- D. Common Divisors CF 182D
- CF-B.Beautiful Divisors
- CF 342A(Xenia and Divisors-考虑有限情况)
- CF 111B Petya and Divisors【想法题+二分(可省略)】
- CF_448E_Divisors
- CF Number With The Given Amount Of Divisors
- CF 558C Amr and Chemistry
- CF 558E(A Simple Task-计数排序+线段树)
- CF 559C
- 1033. 旧键盘打字(20)
- CF-567C - Geometric Progression
- Mahout推荐系统引擎UserCF中的IRStats部分源码解析