SPOJ:Divisors of factorial (hard) (唯一分解&优化)

Factorial numbers are getting big very soon, you‘ll have to compute the number of divisors of such highly composite numbers.

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*1330*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;
}

原文地址:https://www.cnblogs.com/hua-dong/p/9076240.html

时间: 2024-10-20 20:54:03

SPOJ:Divisors of factorial (hard) (唯一分解&优化)的相关文章

SPOJ Python Day1: Factorial

11. Factorial 这个题同样非常简单,就是求一个数的阶乘的尾部有多少个0. 思路是有2*5才会出0,然后2肯定比5多,所以就是数N!中有多少个因子5. 关于如何数出因子5的个数中http://www.chinaunix.net/old_jh/23/926848.html这篇文章介绍的非常详细.我就不谈了,不过想说写程序和算法是两个非常不同的工作,我现在的目标是,大概看一下前人的成法,主要完成编程工作. 最终推出的计算公式为: 当$0 < n < 5$时,$f(n!) = 0$; 当$

SPOJ 15. The Shortest Path 堆优化Dijsktra

You are given a list of cities. Each direct connection between two cities has its transportation cost (an integer bigger than 0). The goal is to find the paths of minimum cost between pairs of cities. Assume that the cost of each path (which is the s

[SPOJ1812]Longest Common Substring II

试题描述 A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is the set of lowercase letters. Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string. Now your t

两个没有解决的和素数(1e8)有关的题

Smallest Number (medium): 求1-N的LCM,多组数据. Divisors of factorial (hard) 求N的阶乘的因子个数. 原文地址:https://www.cnblogs.com/hua-dong/p/9066676.html

SPOJ FCTRL - Factorial

题目链接:http://www.spoj.com/problems/FCTRL/ 题目大意:询问N的阶乘的结果尾数有几个0. 解题思路:考虑问题:N的阶乘的结果能被2m整除,这个m最大为多少. 我们对前N个数除以2,忽略奇数,会得到N/2个数字.那么相当于我们得到了2N/2 对之后的N/2个数字继续除以2,同样忽略奇数.我们会再得到2N/4 ... 所以m=N/2 + N/4 + N/8 +...+0. 那么对于这个问题,我们计算出N的记成被2m1整除的最大m1以及被5m2整除的最大m2,由于2

spoj 4487. Can you answer these queries VI splay 常数优化

4487. Can you answer these queries VI Problem code: GSS6 Given a sequence A of N (N <= 100000) integers, you have to apply Q (Q <= 100000) operations: Insert, delete, replace an element, find the maximum contiguous(non empty) sum in a given interval

[Spoj]Counting Divisors (cube)

来自FallDream的博客,未经允许,请勿转载,谢谢. 设d(x)表示x的约数个数,求$\sum_{i=1}^{n}d(i^{3})$ There are 5 Input files. - Input #1: 1≤N≤10000, TL = 1s. - Input #2: 1≤T≤300, 1≤N≤10^8, TL = 20s. - Input #3: 1≤T≤75, 1≤N≤10^9, TL = 20s. - Input #4: 1≤T≤15, 1≤N≤10^10, TL = 20s. -

SPOJ PGCD - Primes in GCD Table (好题! 莫比乌斯反演+分块求和优化)

PGCD - Primes in GCD Table Johnny has created a table which encodes the results of some operation -- a function of two arguments. But instead of a boring multiplication table of the sort you learn by heart at prep-school, he has created a GCD (greate

动态规划(斜率优化):SPOJ Commando

Commando You are the commander of a troop of n soldiers, numbered from 1 to n. For the battle ahead, you plan to divide these n soldiers into several com-mando units. To promote unity and boost morale, each unit will consist of a contiguous sequence