【题解】洛谷P1445 [Violet]樱花 (推导+约数和)

洛谷P1445:https://www.luogu.org/problemnew/show/P1445

推导过程

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

y=n!+k(kN)

1/x+1/(n!+k)=1/n!

等式两边同乘x*n!*(n!+k)得 n!(n!+k)+xn!=x(n!+k)

移项得 n!(n!+k)=x(n!+k)xn!=xk

x=n!(n!+k)​/k=(n!)2​/k+n!

因为x为正整数 所以(n!)2​/k+n!为正整数0.

因为n!为正整数 所以只要(n!)2​/k为正整数即可

因为k=y-n!   y是可以取到任意正整数的,所以k也可以取到任意正整数,所以这道题就变成了(n!)2的约数个数

思路

求约数个数 线筛的时候我们已经预处理出每个数的最小质因子 直接for一遍1n 不断除以它的最小公约数 直到变成1为止 同时每次都使记录质因数的指数的数组++

这就完成了对每个数分解质因数最后把这些质因数的指数+1乘起来就行了 时间复杂度O(nlogn)

代码

#include<iostream>
#include<cstdio>
using namespace std;
#define Mod 1000000007
#define maxn 1000010
int n,ans=1,cnt;
int p[maxn],c[maxn],v[maxn];
void primes(int x)
{
    for(int i=2;i<=x;i++)
    {
        if(!v[i])
        {
            v[i]=i;
            p[++cnt]=i;
        }
        for(int j=1;j<=cnt;j++)
        {
            if(p[j]>v[i]||p[j]*i>x) break;
            v[p[j]*i]=p[j];
        }
    }
}
int main()
{
    scanf("%d",&n);
    primes(n);//质因数分解 处理出每个数的最小质因子 
    for(int i=1;i<=n;i++)
        for(int j=i;j!=1;j/=v[j])
        c[v[j]]++;//求质因数指数
    for(int i=1;i<=n;i++)
    ans=(long long)ans*(c[i]*2+1)%Mod;
    printf("%d",ans);
}
View Code

猜你喜欢

转载自www.cnblogs.com/BrokenString/p/9656355.html
今日推荐