杜教筛刷一波

很好的学习博客:

http://jiruyi910387714.is-programmer.com/posts/195270.html

https://blog.csdn.net/skywalkert/article/details/50500009


适用范围:

积性(完全积性)函数前缀和,狄利克雷卷积前缀和

注意:

小规模打表,大规模map记忆化,取模

关键点就是卷积哪个函数方便求和

刷题:

51nod1244     

题意:

莫比乌斯函数前缀和1e10

#include<bits/stdc++.h>
#include <hash_map>
#include<tr1/unordered_map>  
using namespace std;
using namespace std::tr1; 
#define ll long long
const int maxn=4600005;
int mu[maxn];
int pri[1000005];
bool isp[maxn];
map<ll,ll>mp;
void init(int n)
{
	mu[1]=1;int p=0;
	for(int i=2;i<=n;i++)
	{
		if(isp[i]==0)mu[i]=-1,pri[++p]=i;
		for(int j=1;j<=p&&i*pri[j]<=n;j++)
		{
			isp[i*pri[j]]=1;
			if(i%pri[j]==0)
			{
				mu[i*pri[j]]=0;
				break;
			}
			else mu[i*pri[j]]=mu[i]*-1;
		}
		mu[i]+=mu[i-1];
	}
}
ll dfs(ll x)
{
	if(x<4600002)return mu[x];
	if(mp[x])return mp[x];
	ll nxt=0;
	ll res=1;
	for(ll i=2;i<=x;i=nxt+1)
	{
		nxt=x/(x/i);
		res-=dfs(x/i)*(nxt-i+1);
		if(nxt==x)break;
	}
	mp[x]=res;
	return res;
}
int main()
{
	ll a,b;
	cin>>a>>b;
	init(min(1ll*4600000,b));
	cout<<dfs(b)-dfs(a-1);
	puts(""); 
} 

hdu5608   这题我会w

题意:

f 狄利克雷卷积 I =n*2-3*n+2   n<1e9,求f前缀和,I(i)=1

思路:

仔细看上面的学习博客

预处理就是枚举d筛掉d的倍数

预处理那块也可以莫比乌斯反演后枚举d

f*I=g  => f*I*miu=g*miu   => f*e=g*miu  =>  f(n)=sigma( g(d)*miu(n/d) [d|n] )

#include<iostream>
#include<stdio.h>
#include<map>
#define ll long long
//#include<tr1/unordered_map>  
using namespace std;
//using namespace std::tr1; 
const int maxn=1e6+5;
const int mod=1e9+7;
ll f[maxn];
void init(int n)
{
	for(int i=1;i<=n;i++)f[i]=(1ll*i*i-3*i+2+mod)%mod;
	for(int i=2;i<=n;i++)
		for(int j=2*i;j<=n;j+=i)
			f[j]=(f[j]-f[i]+mod)%mod;
	for(int i=2;i<=n;i++)f[i]+=f[i-1]%mod,f[i]%=mod; 
}
ll inv(ll t, ll p) {   return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p; }
map<ll,ll>mp;
ll inv6;
ll inv2=500000004;
ll get(ll x)
{
	ll sum=2*x;
	ll t=x*(x+1)%mod*(2*x+1)%mod;
	t=t*inv6%mod;
	sum=(sum+t+mod)%mod;
	t=(3*x*(x+1)%mod)*inv2%mod;
	sum=(sum-t+mod)%mod;
	return sum%mod;
}
ll dfs(ll x)
{
	if(x<=maxn-1)return f[x];
	if(mp[x])	return mp[x];
	ll res= get(x);ll nxt=0;
	for(int i=2;i<=x;i=nxt+1)
	{
		nxt=x/(x/i);
		res=(res-(dfs(x/i)*(nxt-i+1)%mod)+mod)%mod;
	}
	return mp[x]=(res%mod);
}


int main()
{
	int T;inv6=inv(6,mod);
	init(maxn-1);ll n;
	cin>>T;
//	cout<<f[123400]<<endl;
	while(T--)
	{
		scanf("%I64d",&n);
		printf("%I64d\n",dfs(n)%mod);
	}
	
}

第二种预处理

#include<iostream>
#include<stdio.h>
#include<map>
#include<string.h>
//#include<tr1/unordered_map>  
using namespace std;
//using namespace std::tr1; 
#define ll long long
const int maxn=1e6+5;
const int mod=1e9+7;
ll f[maxn];

int pri[500005];
bool isp[maxn];
ll mu[maxn];
void init(int n)
{
	int p=0;mu[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(isp[i]==0) pri[++p]=i,mu[i]=-1;
		for(int j=1;j<=p&&pri[j]*i<=n;j++)
		{
			isp[i*pri[j]]=1;
			if(i%pri[j]==0)
			{
				mu[i*pri[j]]=0;
				break;
			}
			else mu[i*pri[j]]=-mu[i];
		}
	}
	for(ll i=1;i<=n;i++)
	{
		for(ll j=1;i*j<=n;j++)
			f[i*j]+=mu[j]*((i*i-3*i+2+mod)%mod),f[i*j]%=mod;
		f[i]+=f[i-1]%mod,f[i]=(f[i]+mod)%mod;	
	}
}
ll inv(ll t, ll p) {
    return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p;
}
map<ll,ll>mp;
ll inv6;
ll inv2=500000004;
ll get(ll x)
{
	ll sum=2*x;
	ll t=x*(x+1)%mod*(2*x+1)%mod;
	t=t*inv6%mod;
	sum=(sum+t+mod)%mod;
	t=(3*x*(x+1)%mod)*inv2%mod;
	sum=(sum-t+mod)%mod;
	return sum%mod;
}
ll dfs(ll x)
{
	if(x<=maxn-1)return f[x];
	if(mp[x])	return mp[x];
	ll res= get(x);ll nxt=0;
	for(int i=2;i<=x;i=nxt+1)
	{
		nxt=x/(x/i);
		res=(res-(dfs(x/i)*(nxt-i+1)%mod)+mod)%mod;
	}
	return mp[x]=(res%mod);
}


int main()
{
	int T;inv6=inv(6,mod);
	memset(f,0,sizeof(f));
	init(maxn-1);ll n;
	//cout<<f[123400]<<" "<<mu[123400]<<endl;
	cin>>T;
	while(T--)
	{
		scanf("%I64d",&n);
		printf("%I64d\n",dfs(n)%mod);
	}
	
}

猜你喜欢

转载自blog.csdn.net/animalcoder/article/details/79936071