• 樱花,素数筛


    求不定方程
    
    ​1/x+1/y=1/n!
    的正整数解(x,y)的数目。输入一个整数,输出一个整数,表示有多少对 (x,y) 满足题意。答案对10^9+7取模。

    首先分式一定很不好弄,所以我们化分为整,得到(x+y)*n!=xy,移项得(x+y)*n!-xy=0,然后两边加上(n!)2,就变成了(n!)2-(x+y)*n!+xy=(n!)2,左边十字相乘变成(n!-x)*(n!-y),令A=(n!-x),B=(n!-y),则有A*B=(n!)2,然后由唯一分解定理,我们知道n!=p1a1*p2a2*p3a3*……pnan,其中pi为n!的素因子,所以(n!)2=(p1a1*p2a2*p3a3*……pnan2,所以(n!)2有(2*a1+1)*(2*a2+1)*……*(2*an+1)个因子,所以只需要素数筛一遍,然后每一个因子就对应了一个答案。

      但是在写完之后我却t了,在确定自己的素数筛没有问题之后,我在素数筛的代码后面和统计答案的代码后面分别输出了一个l和w,然后我发现当数据为1e6时l很快输出了,w却迟迟输出不了,我本来的意识中是素数并不多,O(n*cnt)(cnt为素数个数)的统计答案是没有什么问题的,可输出cnt的时候我却傻了,cnt是105级别的,不t才怪,于是学习了大佬的方法。具体见代码

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #define ll long long
     4 using namespace std;
     5 const int mod=1e9+7;
     6 const int maxn=1000005;
     7 int n;
     8 ll ans=1;
     9 int a[maxn];
    10 int v[maxn];//以前我的v数组都是bool类型的,只标记他是不是素数,现在是int类型
    11 int prime[maxn],cnt; 
    12 int tmp;
    13 int main()
    14 {
    15     scanf("%d",&n);
    16     for(int i=2;i<=n;++i)
    17     {
    18         if(!v[i])v[i]=i,cnt++,prime[cnt]=i;
    19         for(int j=1;j<=cnt&&i*prime[j]<=n;++j)
    20         {
    21             v[i*prime[j]]=prime[j];//我们知道线性素数筛保证了每个合数被自己最小的素因子筛去,所以v数组就是记录了每个数最小的素因子,顺便的事,不会提高复杂度
    22             if(i%prime[j]==0)break;
    23         }
    24     }
    25     
    26     for(int i=1;i<=n;++i)
    27     {
    28         for(int j=i;j>1;j/=v[j])//直接每次都除以自己的最小的素因子,不用枚举,把复杂度降到nlogn
    29         {
    30             a[v[j]]++,a[v[j]]%=mod;
    31         }
    32     }
    33     for(int i=1;i<=n;++i)
    34         ans*=(2*a[i]+1),ans%=mod;
    35     printf("%lld
    ",ans);
    36     return 0;
    37 } 
  • 相关阅读:
    js 获取时间差
    linq 两个list合并处理,并分组
    单例模式 双锁
    2018年的读书清单
    感悟
    asp.net使用Microsoft.mshtml提取网页标题等解析网页
    //利用反射快速给Model实体赋值
    C# url接口调用
    多字段动态查询
    对图片的操作
  • 原文地址:https://www.cnblogs.com/yuelian/p/12274634.html
Copyright © 2020-2023  润新知