bzoj4916 神犇和蒟蒻
Posted llppdd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4916 神犇和蒟蒻相关的知识,希望对你有一定的参考价值。
神犇和蒟蒻
Time Limit: 10 Sec Memory Limit: 512 MB
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
第一问不会的可以去找豆腐撞死了。。。。(撞之前你可以在想一想看能不能抢救一下。。。)
你输了 1 这道题就做一半了233.。。。
不闹了。。。。
[sum_{i=1}^n phi(i^2)]
[=sum_{i=1}^n phi(i)i]
设 (f(x)= phi(i)i f × id = h)
[h(x)=sum_{d mid n}f(d) frac{d}{n}]
[=sum_{d mid n}mu(d)n]
[=n^2]
你很容易就可以求到了 (id) 和 (h) 的前缀和,就可以杜教筛啦!
你列个式子出来看可以发现 (phi(i^2)=phi(i)i)
然后由于你有个杜教筛的幻想,你要去凑那个卷积。。。。
瞎搞了啊。。。我也很绝望啊。。。
#include<bits/stdc++.h>
using namespace std;
const int N = 2500000, mod = 1e9 + 7;
int tot, prime[N];
long long n, inv6, inv2, phi[N];
bool not_prime[N];
map<int, long long> p;
inline void prepare()
{
phi[1] = 1;
for(int i = 2; i < N; ++i){
if(!not_prime[i]){
prime[++tot] = i; phi[i] = i - 1;
}
for(int j = 1; prime[j] * i < N; ++j){
not_prime[prime[j] * i] = true;
if(i % prime[j] == 0){phi[i * prime[j]] = prime[j] * phi[i]; break;}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
for(int i = 2; i < N; ++i) phi[i] = (phi[i - 1] + phi[i] * i) % mod;
}
long long PHI(long long t)
{
if(t < N) return phi[t];
if(p[t]) return p[t];
long long last, ret = t * (t + 1) % mod * (2 * t + 1) % mod * inv6 % mod;
for(long long i = 2; i <= t; i = last + 1){
last = min(t, t / (t / i));
ret = (ret + mod - (i + last) * (last - i + 1) % mod * inv2 % mod * PHI(t / i) % mod) % mod;
}
p[t] = ret; return ret;
}
inline void get_inv()
{
int p = mod - 2; inv6 = 1; long long tmp = 6;
while(p){
if(p & 1) inv6 = inv6 * tmp % mod;
tmp = tmp * tmp % mod; p >>= 1;
}
p = mod - 2; inv2 = 1; tmp = 2;
while(p){
if(p & 1) inv2 = inv2 * tmp % mod;
tmp = tmp * tmp % mod; p >>= 1;
}
}
int main()
{
prepare(); get_inv();
scanf("%d", &n); printf("1
");
printf("%lld", PHI(n));
return 0;
}
以上是关于bzoj4916 神犇和蒟蒻的主要内容,如果未能解决你的问题,请参考以下文章