您的位置:首页 > 其它

2721: [Violet 5]樱花 思路题 线性筛素数

2016-02-15 09:20 531 查看
思路还是挺巧妙的。。我数论还是太弱了。

首先容易发现x,y一定>n!,那么不妨设y=n!+z,那么x=n!+n!^2/z。

我们要求z的数量,也就是求n!^2的约数个数。

若n!^2=pa^a1*p2^a2…pn^an,那么n!^2的约数个数为(a1+1)(a2+1)*…(an+1)。(好像昨天在一篇blog写过一次了)。

我们可以根据阶乘的定义来算出约数个数,对于素数就直接计算,对于合数,我们可以在线性筛的时候记录下它的最小质因子(因为每个合数只会被它的最小质因子筛掉一次,因而保证了线性),从而求出每个合数的所有质因子。最后统计答案,不要忘记有个平方所以出现了两次。

#include<iostream>
#include<cstdio>
#define ll long long
#define p 1000000007
using namespace std;
int n;
ll ans=1;
int prime[1000005],pos[1000005],cnt[1000005];
bool flag[1000005];
inline void get_prime()
{
for (int i=2;i<=n;i++)
{
if (!flag[i]) prime[++prime[0]]=i,pos[i]=prime[0];
for (int j=1;j<=prime[0]&&i*prime[j]<=n;j++)
{
flag[i*prime[j]]=1; pos[i*prime[j]]=j;
if (i%prime[j]==0) break;
}
}
}
int main()
{
scanf("%d",&n);
get_prime();
for (int i=1;i<=n;i++)
{
int tmp=i;
while (tmp!=1) cnt[pos[tmp]]++,tmp/=prime[pos[tmp]];
}
for (int i=1;i<=prime[0];i++) ans=ans*((2*cnt[i]+1)%p)%p;
cout << ans << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: