[bzoj4916] 神犇和蒟蒻

Description

很久很久以前,有一只神犇叫yzy;

很久很久之后,有一只蒟蒻叫lty;

Input

请你读入一个整数N;1<=N<=1E9,A、B模1E9+7;

Output

请你输出一个整数\(A=\sum_{i=1}^N{\mu (i^2)}\)

请你输出一个整数\(B=\sum_{i=1}^N{\varphi (i^2)}\)

Sample Input

1

Sample Output

1
1

solution

杜教筛基础题.

对于第一问,由于当\(i\geqslant 2\)的时候\(\mu(i^2)=0\),所以直接puts("1")就好了.

\[f(n)=\varphi(n^2)=\varphi(n)*n\\ S(n)=\sum_{i=1}^{n}f(i) \]

然后把杜教筛的套路式子搬出来:

\[S(n)=\sum_{i=1}^{n}(f*g)(i)-\sum_{i=2}^{n}g(i)S(\lfloor\frac{n}{i}\rfloor) \]

然后考虑凑出这个\(g\)

\[(f*g)(n)=\sum_{i|n}i*\varphi(i)*g(\frac{n}{i}) \]

看到这个系数\(i\)很不爽,考虑把他消掉,令\(g(n)=n\),得:

\[(f*g)(n)=\sum_{i|n}i*\varphi(i)*\frac{n}{i}=n*\sum_{i|n}\varphi(i)=n^2 \]

然后发现这个东西的前缀和很好求,就直接带到套路式里得:

\[S(n)=\frac{n(n+1)(2n+1)}{6}-\sum_{i=2}^niS(\lfloor\frac{n}{i}\rfloor) \]

然后记忆化一下,递归求这个,线筛出前\(1e7\)就做完了.

#include<bits/stdc++.h>
using namespace std;

#define int long long 

void read(int &x) {
	x=0;int f=1;char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
	for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
	if(x<0) x=-x,putchar('-');
	if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

const int maxn = 1e7+1;
const int mod = 1e9+7;

int phi[maxn],pri[maxn],vis[maxn],n,tot,inv2,inv6;

void sieve() {
	phi[1]=1;
	for(int i=2;i<maxn;i++) {
		if(!vis[i]) pri[++tot]=i,phi[i]=i-1;
		for(int t,j=1;j<=tot&&i*pri[j]<maxn;j++) {
			vis[t=i*pri[j]]=1;
			if(!(i%pri[j])) {phi[t]=phi[i]*pri[j];break;}
			phi[t]=phi[i]*phi[pri[j]];
		}
	}
	for(int i=1;i<maxn;i++) phi[i]=(phi[i-1]+phi[i]*i)%mod;
}

map<int,int > Phi;

int qpow(int a,int x) {
	int res=1;
	for(;x;x>>=1,a=a*a%mod) if(x&1) res=res*a%mod;
	return res;
}

int calc(int n) {return n%mod*(n%mod+1)%mod*inv2%mod;}

int sum(int n) {
	if(n<maxn) return phi[n];
	if(Phi[n]) return Phi[n];
	int res=n*(n+1)%mod*(n+n+1)%mod*inv6%mod;
	int T=2;//printf("%lld\n",Phi[n]);
	while(T<=n) {
		int pre=T;T=n/(n/T);
		res=(res-sum(n/T)*(calc(T)-calc(pre-1))%mod)%mod;T++;
	}
	return Phi[n]=(res%mod+mod)%mod;
}

signed main() {
	sieve();inv2=qpow(2,mod-2);inv6=qpow(6,mod-2);
	int n;read(n);write(1ll),write(sum(n));
	return 0;
}

posted @ 2018-12-05 16:16  Hyscere  阅读(308)  评论(0编辑  收藏  举报