版权声明:转载什么的无所谓啦,反正注明一下出处就行啦~ https://blog.csdn.net/u013672056/article/details/76220132
首先是线性筛
由于每一个数只会被筛一次,所以复杂度为on
筛mobius函数
void init()
{
memset(book,0,sizeof(book));
memset(mu,0,sizeof(mu));
memset(prime,0,sizeof(prime));
mu[1]=1;cnt=0;
for(int i=2;i<=n;i++)
{
if(!book[i])
prime[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&prime[j]*i<=n;j++)
{
book[i*prime[j]]=1;
if(i%prime[j]) mu[i*prime[j]]=-mu[i];//如果不整除
else//否则就跳出
{
mu[i*prime[j]]=0;
break;
}
}
}
}
hdu 1695 无优化
#pragma GCC optimize("O2")
#include<cstdio>
#include<string>
#define maxn 100100
#define int long long
using namespace std;
int cnt,a,b,c,d,k,ans1,ans2,mu[maxn],prime[maxn],book[maxn],t;
void init()
{
mu[1]=1,cnt=0;
for(int i=2;i<=maxn;i++)
{
if(!book[i]) prime[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&prime[j]*i<=maxn;j++)
{
book[i*prime[j]]=1;
if(i%prime[j]) mu[i*prime[j]]=-mu[i];
else
{
mu[i*prime[j]]=0;
break;
}
}
}
}
main()
{
init();
scanf("%lld",&t);
for(int kase=0;t;t--)
{
scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);
if(k==0){ printf("Case %lld: 0\n",++kase);continue;}
ans1=ans2=0;
d/=k,b/=k;
for(int i=1;i<=min(b,d);i++)
ans1+=mu[i/1]*(d/i)*(b/i);
for(int i=1;i<=min(b,d);i++)
ans2+=mu[i/1]*(min(b,d)/i)*(min(b,d)/i);
printf("Case %lld: %lld\n",++kase,ans1-ans2/2);
}
return 0;
}
BZOJ2301
#pragma GCC optimize("O2")
#include<cstdio>
#include<string>
#define maxn 60100
using namespace std;
int cnt,a,b,c,d,k,ans1,ans2,mu[maxn],prime[maxn],book[maxn],t,sum[maxn];
template<typename tp>void read(tp & dig)
{
char c=getchar();dig=0;
while(!isdigit(c))c=getchar();
while(isdigit(c))dig=dig*10+c-'0',c=getchar();
}
inline void init()
{
mu[1]=sum[1]=1,cnt=0;
for(int i=2;i<=maxn;i++)
{
if(!book[i]) prime[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&prime[j]*i<=maxn;j++)
{
book[i*prime[j]]=1;
if(i%prime[j]) mu[i*prime[j]]=-mu[i];
else
{
mu[i*prime[j]]=0;
break;
}
}
sum[i]=sum[i-1]+mu[i];
}
}
inline int calc(int l,int r)
{
if(l>r) swap(l,r);
int ans=0;
for(int i=1,last=0;i<=l;i=last+1)
{
last=min(l/(l/i),r/(r/i));//move to the next equal to the val
ans+=(sum[last]-sum[i-1])*(l/i)*(r/i);
}
return ans;
}
main()
{
init();
read(t);
for(;t;t--)
{
read(a),read(b),read(c),read(d),read(k);
int ans=calc(b/k,d/k)-calc((a-1)/k,d/k)-calc(b/k,(c-1)/k)+calc((a-1)/k,(c-1)/k);
printf("%d\n",ans);
}
return 0;
}