51 NOD 1189 阶乘分数(素因子分解+推公式+求逆元)

来源:互联网 发布:剑灵捏脸数据收费怎办 编辑:程序博客网 时间:2024/05/17 04:15

传送门
1189 阶乘分数
题目来源: Spoj
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
1/N! = 1/X + 1/Y,给出N,求满足条件的整数解的数量。例如:N = 2,1/2 = 1/3 + 1/6,1/2 = 1/4 + 1/4。由于数量可能很大,输出Mod 10^9 + 7。
Input
输入一个数N(1 <= N <= 1000000)。
Output
输出解的数量Mod 10^9 + 7。
Input示例
2
Output示例
2
解题思路:
首先我们将上面的式子化成一个整式,也就是化为

N!(X+Y)=XY

将两边同时加上一个N!^2,化为:
N!(X+Y)+N!2=XY+N!2

(XN!)(YN!)=N!2

又因为X和Y是整数,所以我们只需要将N!进行素因子分解就行了,不要忘记最后+1除以2,因为要去重,除以2的时候这里需要求一下逆元,在分解素因子的时候有一个窍门,我们只需要统计N!里面有多少个素因子就行了,上代码:

#include <iostream>#include <cstring>#include <cstdio>using namespace std;typedef long long LL;const int MAXN = 1e6+5;typedef long long LL;const LL MOD = 1e9+7;LL p[MAXN];bool prime[MAXN];int k;void isprime(){    memset(prime, 0, sizeof(prime));    LL i, j;    k = 0;    for(i=2; i<MAXN; i++)    {        if(!prime[i])        {            p[k++] = i;            for(j=i*i; j<MAXN; j+=i)            {                prime[j] = 1;            }        }    }}LL get(LL m, LL p)///m!里面有多少个p{    if(m == 0)        return 0;    return m/p+get(m/p, p);}void Exgcd(LL a, LL b, LL &x, LL &y){    if(b == 0)    {        x = 1;        y = 0;        return;    }    LL x1, y1;    Exgcd(b, a%b, x1, y1);    x = y1;    y = x1-(a/b)*y1;}int main(){    isprime();    int n;    LL x, y;    Exgcd(2LL, MOD, x, y);    LL inv = (x%MOD+MOD)%MOD;    while(cin>>n)    {        LL ans = 1;        for(int i=0; i<k&&p[i]<=n; i++)        {            LL tmp = get(n, p[i])*2+1;///N!^2            tmp %= MOD;            ans = (ans*tmp)%MOD;        }        ans = ((ans+1)*inv)%MOD;        cout<<ans<<endl;    }    return 0;}/**                   _ooOoo_                  o8888888o                  88" . "88                  (| -_- |)                  O\  =  /O               ____/`---'\____             .'  \\|     |//  `.            /  \\|||  :  |||//  \           /  _||||| -:- |||||-  \           |   | \\\  -  /// |   |           | \_|  ''\---/''  |   |           \  .-\__  `-`  ___/-. /         ___`. .'  /--.--\  `. . __      ."" '<  `.___\_<|>_/___.'  >'"".     | | :  `- \`.;`\ _ /`;.`/ - ` : | |     \  \ `-.   \_ __\ /__ _/   .-` /  /======`-.____`-.___\_____/___.-`____.-'======                   `=---='^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^         佛祖保佑       每次AC**/
0 0
原创粉丝点击