您的位置:首页 > 其它

HYSBZ - 2818(gcd(n,m)为素数的对数

2017-08-21 15:38 337 查看
传送门

拓展版:

题意:给定两个数



,其中



,求

为质数的

有多少对?其中



的范

     围是



开始瞎BB:
 


对于本题,我们设

 

     

为满足







的对数

     

为满足







的对数

 

     那么,很显然

,反演后得到




因为题目要求是

为质数,那么我们枚举每一个质数

,然后得到

 

     


 

     如果直接这样做肯定TLE,那么我们必须优化。

 

     我们设

,那么继续得到



首先线性筛法的原理是枚举,小于等于的质数。

使得,即使得p[j]是k的最小质因数。 从而使得任何数只能由最小质因数转移过来,唯一了化转移方程,从而达到线性。








   


#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <cstdio>
#include <set>
#include <cmath>
#include <map>
#include <algorithm>
#define INF 0x3f3f3f3f
#define LL long long
#define Mod 10001
using namespace std;
#define MAXN 10000006
int mu[MAXN],prime[MAXN],top,f[MAXN],g[MAXN],sum[MAXN];
bool vis[MAXN];
const int UB=1e7;

void getmu()
{
int i,j,k;
mu[1]=1;
g[1]=0;
for(i=2; i<=UB; i++)
{
if(!vis[i])//单素数
{
prime[top++]=i;
mu[i]=-1;
g[i]=1;
}
for(j=0; (k=prime[j]*i)<=UB; j++)
{
vis[k]=1;
if(i%prime[j])//i=p2^a2*...pm^am
{
g[k]=mu[i]-g[i];
mu[k]=-mu[i];
}
else//i=p1^a1*...pm^am
{
mu[k]=0;
g[k]=mu[i];
break;
}
}
}
/*for(i=1;i<=100;i++)
{
sum=0;
for(j=2;j<=i;j++)
{
if(i%j==0&&!vis[j])
{
sum+=mu[i/j];
}
}
printf("%d:%d %d\n",i,sum,g[i]);///对拍
}*/
}
int main()
{
getmu();
int t=1;
//cin>>t;
//freopen("1.in","r",stdin);
//freopen("3.txt","w",stdout);
while(t--)
{
LL n,m;
//scanf("%lld%lld",&n,&m);
while(scanf("%lld",&n)!=EOF)
{
m=n;
if(n>m)
swap(n,m);
LL ans=0;
for(int i=1;i<=n;i++)
{
LL t=n/i;
ans=ans+(n/i)*(m/i)*g[i];
//cout<<n/i*m/i<<" "<<(n/i)*(m/i)<<endl;
}
cout<<ans<<endl;
}
}
return 0;
}
上式是2818的代码,改一下则为增强版
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: