题意:

已知\(N^2-3N+2=\sum_{d|N}f(d)\),求\(\sum_{i=1}^nf(i) \mod 1e9+7\),\(n\leq1e9\)

思路:

杜教筛基础题?

很显然这里已经设了一个\(F(n) = \sum_{d|n}f(d)\),那么由莫比乌斯反演可以得到\(f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})\)。

然后卷积可以看出卷一个\(I\)比较好,则:\((f*g)(n)=\sum_{i=1}^nF(i)-\sum_{i=2}^nS(\lfloor\frac{n}{i}\rfloor)\)。显然\(F(i)\)前缀可以通过平方和公式等推出来。那么直接递归做即可。

代码:

#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 1e6 + 5;
const ll MOD = 1e9 + 7;
const ull seed = 131;
const int INF = 0x3f3f3f3f; int mu[maxn], vis[maxn];
int prime[maxn], cnt;
ll sum[maxn];
ll F(ll x){
return (1LL * x * x - 3 * x + 2) % MOD;
}
void getmu(int n){
memset(vis, 0, sizeof(vis));
cnt = 0;
mu[1] = 1;
for(int i = 2; i <= n; i++) {
if(!vis[i]){
prime[cnt++] = i;
mu[i] = -1;
}
for(int j = 0; j < cnt && prime[j] * i <= n; j++){
vis[prime[j] * i] = 1;
if(i % prime[j] == 0){
mu[i * prime[j]] = 0;
break;
}
mu[i * prime[j]] = -mu[i];
}
} for(int i = 1; i <= n; i++){
for(int j = i; j <= n; j += i){
sum[j] = (sum[j] + mu[i] * F(j / i)) % MOD;
}
sum[i] = (sum[i] + sum[i - 1]) % MOD;
}
} int N = 1e6;
map<int, ll> mm;
ll ksc(ll a, ll b, ll p){
ll t = a * b - (ll)((long double)a * b / p + 0.5) * p;
return (t < 0)? t + p : t;
}
ll inv6 = 166666668, inv2 = 500000004;
ll solve(ll n){
if(n <= N) return sum[n];
if(mm.find(n) != mm.end()) return mm[n];
ll ans = ksc(ksc(n, n + 1, MOD), 2 * n + 1, MOD) * inv6 % MOD;
ans = (ans - ksc(n, n + 1, MOD) * inv2 % MOD * 3) % MOD;
ans += 2LL * n;
ans %= MOD;
for(int l = 2, r; l <= n; l = r + 1){
r = n / (n / l);
ans -= 1LL * (r - l + 1) * solve(n / l);
ans %= MOD;
}
return mm[n] = ans; }
ll ppow(ll a, ll b, ll p){
ll ret = 1;
while(b){
if(b & 1) ret = ret * a % p;
a = a * a % p;
b >>= 1;
}
return ret;
}
int main(){
int T;
getmu(N);
// printf("* %lld\n", sum[N + 1]);
scanf("%d", &T);
mm.clear();
while(T--){
ll n;
scanf("%lld", &n);
printf("%lld\n", (solve(n) + MOD) % MOD);
}
return 0;
}

最新文章

  1. MFC编程入门之二十五(常用控件:组合框控件ComboBox)
  2. [软件架构]模块化编程思想及(C++)实践
  3. HDU 5441 离线处理 + 并查集
  4. UIButton的titleEdgeInsets和imageEdgeInsets属性
  5. org.springframework.web.context.ContextLoaderListen 报错解决办法
  6. sql大全
  7. nginx支持cgi(c,c++)
  8. poj 2631 Roads in the North
  9. ORACLE EXP命令
  10. COJ 1010 WZJ的数据结构(十) 线段树区间操作
  11. HashSet的分析(转)
  12. 简单三段式状态机实验2-LCD12864
  13. 解决PL/SQL Developer 连接oracle 11g 64位中的问题
  14. HashMap 之弱引用 - WeakHashMap
  15. 浅谈static其一之不死变量
  16. C#编写扫雷游戏
  17. Ubuntu - Start - 必要软件安装
  18. python_flask 基础巩固 (URL_FOR 详解)
  19. table的复制 SqlServer 数据库添加临时表(select 字段1,字段2,字段3 into)
  20. 洛谷 P2345 奶牛集会 解题报告

热门文章

  1. luogu P2198 杀蚂蚁
  2. 聊聊.net应用程序的Docker镜像
  3. C++11中string与数值类型的转换
  4. Compile-time Dependency Injection With Go Cloud&#39;s Wire 编译时依赖注入 运行时依赖注入
  5. PL/SQL 遇到问题
  6. JavaScript 类型、原型与继承学习笔记
  7. Spring Boot 基础,理论,简介
  8. 前端开发规范之命名规范、html规范、css规范、js规范
  9. HttpClientUtils:Http请求工具类
  10. Chrome标签整理