济南学习D3T1__线性筛和阶乘质因数分解

【问题描述】

从1− N中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数最大可能是多少。

【输入格式】

第一行一个数字N。

【输出格式】

一行,一个整数代表答案对100000007取模之后的答案。

【样例输入】

7

【样例输出】

144

【样例解释】

但是塔外面有东西。

【数据规模与约定】

对于20%的数据,1<=N<=100。

对于50%的数据,1<=N<=5000。

对于70%的数据,1<=N<=10^5。      

对于100%的数据,1<=N<=5*10^6。

 ________________________________________________________________

这个题并没有太好的办法,后来看了题解,才知道对N的阶乘进行质因数分解。于是用了筛法和快速幂,可是超时,只过了60分。于是学习了线性快速幂,时间少了,可还是60分,没解决根本问题。后来看了阶乘的质因数分解,很神奇!!!

将这个神奇的东西做一下介绍(引自网络):

求m!分解质因数后因子n的个数。
这道题涉及到了大数问题,如果相乘直接求的话会超出数据类型的范围。
下面给出一种效率比较高的算法,我们一步一步来。
m!=1*2*3*……*(m-2)*(m-1)*m
可以表示成所有和n倍数有关的乘积再乘以其他和n没有关系的
=(n*2n*3n*......*kn)*ohter other是不含n因子的数的乘积因为kn<=m 而k肯定是最大值所以k=m/n
=n^k*(1*2*......*k)*other 
=n^k*k!*other
从这个表达式中可以提取出k个n,然后按照相同的方法循环下去可以求出k!中因子n的个数。
每次求出n的个数的和就是m!中因子n的总个数。

 

我的理解:

1、m!=1*2*3*……*m,里面肯定有n的整数倍,也就是1*2*……n……2*n……3*n……k*n……m;

2、里面有几个n的倍数就在M!中有几个n,于是m/n个;

3、可是还有些特殊情况,如n*n,n*n*n,这样在m/n的得数中再除n,再除n,再除n,……知道为0;

 

关于线性筛法要注意:

if(i%ss[j]==0)break;

__________________________________________________________________

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int m=5000001;
 8 const int md=100000007;
 9 int n,js=0;
10 long long ans=1;
11 long long sz[m],ss[m],cs[m];
12 void sss()//线性筛法
13 {
14     memset(sz,-1,sizeof(sz));
15    for(int i=2;i<m;i++)
16    {
17            if(sz[i])ss[js++]=i;
18            for(int j=0;j<js&&i*ss[j]<m;j++)
19            {
20                sz[i*ss[j]]=0;
21               if(i%ss[j]==0)break;
22            }
23    }
24 }
25 void fj(int i)//n的阶乘中含有多少个ss[i],时间复杂度可能是logxn(感觉是)
26 {
27     int x=ss[i];
28     int k=n;
29     while(k)
30     {
31         k=k/x;
32         cs[i]+=k;
33     }
34 }
35 long long  por(long long x,long long y)//快速幂
36 {
37     if(y%2)y=y-1;
38     x=x%md;
39     long long anss=1;
40     long long ds=x;
41     for(;y>0;y>>=1)
42     {
43         if(y&1)anss*=ds;
44         anss%=md;
45         ds=(ds%md)*(ds%md)%md;
46     }
47     return anss;
48 }
49 int main()
50 {
51      freopen("hao.in","r",stdin);
52      freopen("hao.out","w",stdout);
53     scanf("%d",&n);
54     sss();
55     for(int i=0;i<js;i++)
56     fj(i);
57     for(int i=0;i<js;i++)
58     {
59         ans*=por(ss[i],cs[i]);
60         ans%=md;
61     }
62     cout<<ans; 
63       fclose(stdout);
64       fclose(stdin);
65     return 0;
66 }
原文地址:https://www.cnblogs.com/gryzy/p/6050054.html