SPOJ:Divisors of factorial (hard) (唯一分解&分块优化)
2018-05-23 12:21
489 查看
Factorial numbers are getting big very soon, you'll have to compute the number of divisors of such highly composite numbers.
On the next T lines, you will be given two integers N and M.
Since the answer can get very big, output it modulo M.
For N, M : uniform random input in the range.
One input file.
题意: T组数据 给定N,M ; 求N的阶乘的因子个数 , 结果模M .
思路: 对于求某个数的因子个数 , 我们知道是唯一分解为素数 ,表示为素数的幂的乘积形式a1^p1*a2^p2... 然后结果就是所有(p1+1)*(p2+1)...的乘积.
但是这里的N的阶乘过大, 而且多组询问, T也过大 ,而且需要模不同的M (即可能不能离线求).
考虑到对于大于10000的素数 最多除一次 所以单独考虑 即把前面1229个素数和后面第1230个素数到最后一个素数分开考虑 :前面的暴力除,复杂度1229*logN
后面部分分块 把除数相同的合并. 然后快速幂, 复杂度logN*logN
所以最后的复杂度是O(T*1230*logN)
Input
The first line contains an integer T, the number of test cases.On the next T lines, you will be given two integers N and M.
Output
Output T lines, one for each test case, with the number of divisors of the factorial of N.Since the answer can get very big, output it modulo M.
Example
Input: 3 2 1000 3 11 4 5 Output: 2 4 3
Constraints
0 < T < 5432 1 < N < 10^8 1 < M < 10^9
For N, M : uniform random input in the range.
One input file.
题意: T组数据 给定N,M ; 求N的阶乘的因子个数 , 结果模M .
思路: 对于求某个数的因子个数 , 我们知道是唯一分解为素数 ,表示为素数的幂的乘积形式a1^p1*a2^p2... 然后结果就是所有(p1+1)*(p2+1)...的乘积.
但是这里的N的阶乘过大, 而且多组询问, T也过大 ,而且需要模不同的M (即可能不能离线求).
考虑到对于大于10000的素数 最多除一次 所以单独考虑 即把前面1229个素数和后面第1230个素数到最后一个素数分开考虑 :前面的暴力除,复杂度1229*logN
后面部分分块 把除数相同的合并. 然后快速幂, 复杂度logN*logN
所以最后的复杂度是O(T*1230*logN)
#include<bits/stdc++.h> typedef long long ll; using namespace std; const int maxn=1e8; const int Mod=1e9+7; int p[6000000],vis[maxn+10],cnt; void prime() { for(int i=2;i<=maxn;i++){ if(!vis[i]) p[++cnt]=i; for(int j=1;j<=cnt&&(ll)i*p[j]<=maxn;j++){ vis[i*p[j]]=1; if(!(i%p[j])) break; } } } int qpow(int a,int x,int M){ int res=1; while(x){ if(x&1) res=(ll)res*a%M; a=(ll)a*a%M; x>>=1; } return res; } int main() { int T,i,j,x,M,pos,ans; prime(); scanf("%d",&T); for(i=1;i<=T;i++){ ans=1; scanf("%d%d",&x,&M); for(j=1;j<1230&&p[j]<=x;j++){ //暴力部分 int tmp=x,num=0; while(tmp){ num+=tmp/p[j]; tmp/=p[j]; } ans=(ll)ans*(num+1)%M; } pos=upper_bound(p+1,p+cnt+1,x)-p; pos--; int fcy; for(j=1230;j<=pos;j=fcy+1){ //合并部分 fcy=upper_bound(p+1,p+cnt+1,x/(x/p[j]))-p; fcy--; if(fcy>pos) fcy=pos; ans=(ll)ans*qpow(x/p[j]+1,fcy-j+1,M)%M; } printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU6069 2017 Multi-University Training Contest - Team 4 1003 Counting Divisors(唯一分解定理+思维优化)
- Spoj-ODDDIV Odd Numbers of Divisors
- UVa 294 - Divisors(唯一分解)
- poj 1845Sumdiv(唯一分解定理&&约数和公式&&二分求等比数列和&&反复平方法计算p^n幂~~~好多定理啊)
- HDU 3415 Max Sum of Max-K-sub-sequence - dp&单调队列优化
- LuoguP3927 SAC E#1 - 一道中档题 Factorial 解题报告【唯一分解定理】
- POJ 1236 Network of Schools【强连通分量分解&&缩点||tarjan&&缩点】
- Maximum function nesting level of '100' reached, aborting!--漫谈递归:PHP里的尾递归及其优化
- 【唯一分解定理 && 状态压缩 && 组合数学】LightOJ - 1236 Pairs Forming LCM
- HDU 1215 七夕节 【约数和定理&&唯一分解定理(模板)】
- JFFS2 error: (1) jffs2_build_inode_pass1: child dir "udhcpc" (ino #440) of dir ino #336 appears to be a hard link
- HDU5579 LCM & 唯一分解定理 & 排列组合
- Gym 100952G&&2015 HIAST Collegiate Programming Contest G. The jar of divisors【简单博弈】
- SPOJ ODDDIV - Odd Numbers of Divisors
- LightOJ 1236 - Pairs Forming LCM (LCM·唯一分解)
- HDU1452:Happy 2004(数论 & 唯一分解)
- UVA 294 Divisors(唯一分解定理 + 除数函数)
- tyvj 4877 组合数 唯一分解定理+前缀和优化
- SPOJ:Harbinger vs Sciencepal(分配问题&不错的DP&bitset优化)
- hdoj 1492 The number of divisors(约数) about Humble Numbers 【数论】【质因子分解 求和】