问题 E: 樱花

时间限制1 Sec  内存限制128 MB
提交27  解决9
[
提交][状态][讨论版][命题人:150112200121][Edit] [TestData]

题目链接:http://acm.ocrosoft.com/problem.php?cid=1701&pid=4

题目描述

求不定方程:

1/x+1/y=1/n!

的正整数解 (x,y)(x,y)(x,y) 的数目。

输入

一个整数 n

对于 30% 的数据,n100
对于全部数据,1n106
 

输出

一个整数,表示有多少对 (x,y) 满足题意。答案对 109+7 取模。

样例输入

2

样例输出

3

思路:将x设为=n!+a,y=n!+b可以将原式化为a*b=(n!)*(n!),相当于在算(n!)*(n!)有几个因数,然后排列组合推出,因数个数和为(c1+1)*(c2+1)......ck为质因数分解后各个质数的幂指数,具体见代码。

 

代码:

#include<bits/stdc++.h>

using namespace std;

#define ll long long

#define mod 1000000007

#define maxn 1000005

#define INF 0x3f3f3f3f

int v[maxn], prime[maxn][2];

int m = 0;

void xianxing(int n)//线性筛

{

    for (int i = 2; i <= n; i++)

    {

         if (v[i] == 0)

         {

             v[i] = i;

             prime[++m][0] = i;

         }

         for (int j = 1; j <= m; j++)

         {

             if (prime[j][0] > v[i] || prime[j][0] * i > n)

             {

                  break;

             }

             v[i*prime[j][0]] = prime[j][0];

         }

    }

    /*for (int i = 1; i <= m; i++)

    {

         cout << prime[i] << " ";

    }*/

}

int main()

{

    //将x设为=n!+a,y=n!+b可以将原式化为a*b=(n!)*(n!),相当于在算(n!)*(n!)有几个因数

    xianxing(1000000);//线性筛

    int n;

    cin >> n;

    int sum = 0;

    for (int i = 1; i <= m; i++)//利用n!中p(p为质数)的个数为  求和n/(p的k次方) ,k为1到正无穷,将n!质因数分解

    {

         if (prime[i][0] > n)break;//质数都比输入的大了,没必要去判断了,直接break

         for (int j = 1; j <= 1000000; j++)

         {



             if (pow(prime[i][0], j) > n)break;//后面全为0,加了也没意义,直接break

             //cout<<pow(prime[i][0],j)<<endl;

             prime[i][1] += int(n / pow(prime[i][0], j));

             //cout<<prime[i][1]<<" ";

             //cout<<int(n/pow(prime[i][0],j))<<" ";

         }

         sum++;

         //cout<<endl;

    }

    //cout<<sum<<endl;

    /*

    for(int i=1;i<=sum;i++)

    {

         cout<<prime[i][1]<<endl;

    }*/

    for (int i = 1; i <= sum; i++)

    {

         prime[i][1] *= 2;//(n!)*(n!)的各个因数的个数刚好是n!各个个数的两倍

    }

    ll result = 1;

    //排列组合推出,因数个数和为(c1+1)*(c2+1)......ck为质因数分解后各个质数的幂指数

    for (int i = 1; i <= sum; i++)

    {

         result = ((result%mod)*(prime[i][1] + 1) % mod) % mod;

    }

    cout << result << endl;

}