Description

\(T\) 组询问,定义 \(F(n)=\sum\limits_{d|n}d\)。每次给出 \(n,m,a\) 求

\[\sum\limits_{i=1,j=1,F(\gcd(i,j)) \leq a}^{i\leq n, j \leq m} F (\gcd(i,j))
\]

\(T \leq 20000;n,m,a\leq 10^5\)

Solution

首先 \(F\) 可以直接暴力地 \(O(n \log n)\) 筛出来。

考虑 \(a\) 的限制不是很好处理,假设没有这个 \(a\) 的限制,则所求为

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m} F (\gcd(i,j))
\]

令 \(G(i)=\sum\limits_{x=1}^{n}\sum\limits_{y=1}^{m}[\gcd(x,y)=i]\)。这个东西是什么呢?在 这里 有它的推导过程。根据里面的过程,可以得到 \(G(i) = \sum\limits_{d=1}^{\lfloor\frac{n}{i}\rfloor}\mu(d)\lfloor\frac{n}{id}\rfloor\lfloor\frac{m}{id}\rfloor\)(默认 \(n \leq m\))

令下面的过程中\(t = id\),则所求的是

\[\begin{aligned}&\sum\limits_{i=1}^{n}F(i)G(i) \\ &= \sum\limits_{i=1}^{n}F(i)\sum\limits_{d=1}^{\lfloor\frac{n}{i}\rfloor}\mu(d)\lfloor\frac{n}{id}\rfloor\lfloor\frac{m}{id}\rfloor \\ &=\sum\limits_{i=1}^{n}F(i)\sum\limits_{i | t}\mu(\frac{t}{i})\lfloor\frac{n}{t}\rfloor\lfloor\frac{m}{t}\rfloor \\ &= \sum\limits_{t=1}^{n}\lfloor\frac{n}{t}\rfloor\lfloor\frac{m}{t}\rfloor\sum\limits_{i | t}F(i)\mu(\frac{t}{i})\end{aligned}
\]

观察后面的式子,正好是一个狄利克雷卷积的形式。这种样子的都可以类似于那种 \(O(n \log n)\) 地质数筛法在调和级数内求出来,再结合分块就可以做完这个没有 \(a\) 的题。

现在有了 \(a\) 的限制之后,离线。把询问按照 \(a\) 从小到大排序,然后按照 \(F(i)\) 从小到大加入。每当有一个新的 \(a\) ,就可以移动指针,将一些 \(F\) 用处理 \(\sum\limits_{i | t}F(i)\mu(\frac{t}{i})\) 的方式加入到这个里面。然后加入完之后用分块计算就行。

现在需要维护单点操作,查询前缀和,树状数组是不错的选择。

由于取模是 \(2^{32} - 1\) ,可以直接 int 自然溢出最后和 \(2147483647\) 取一个 & 就行了。

时间复杂度:\(O(n + n \log n + n \log ^ 2 (n) + T \log (n)\sqrt n)\)

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 100000;
int T, cnt, flag[N + 5], p[N + 5], F[N + 5], mu[N + 5], ans[N + 5];
inline void prework() {
flag[1] = mu[1] = 1;
for(int i = 2; i <= N; i++) {
if(!flag[i]) { p[++cnt] = i, mu[i] = -1; }
for(int j = 1; j <= cnt && i * p[j] <= N; j++) {
flag[i * p[j]] = 1; if(i % p[j] == 0) {
mu[i * p[j]] = 0; break ;
} mu[i * p[j]] = mu[i] * -1;
}
}
for(int i = 1; i <= N; i++)
for(int j = i; j <= N; j += i) F[j] += i;
}
int c[N + 5];
inline int lb(int x) { return x & (-x); }
inline void add(int x, int d) {
for(int i = x; i <= N; i += lb(i)) c[i] += d;
}
inline int sum(int x) {
int ret = 0;
for(int i = x; i; i -= lb(i))
ret += c[i]; return ret;
}
inline int calc(int n, int m) {
int ret = 0;
for(int l = 1, r; l <= min(n, m); l = r + 1) {
r = min(n / (n / l), m / (m / l));
ret += (n / l) * (m / l) * (sum(r) - sum(l - 1));
} return ret;
}
struct Query {
int n, m, a, id;
inline bool operator < (const Query &x) const {
return a < x.a;
}
}Q[N + 5];
struct node {
int id, d;
inline bool operator < (const node &x) const {
return d < x.d;
}
}A[N + 5];
int main() {
prework(); scanf("%d", &T);
for(int i = 1; i <= T; i++) scanf("%d %d %d", &Q[i].n, &Q[i].m, &Q[i].a), Q[i].id = i;
for(int i = 1; i <= N; i++) A[i].d = F[i], A[i].id = i;
sort(Q + 1, Q + T + 1); sort(A + 1, A + N + 1); int pos = 0;
for(int i = 1; i <= T; i++) {
while(pos < N && A[pos + 1].d <= Q[i].a) {
++pos;
for(int j = 1; A[pos].id * j <= N; j++)
add(j * A[pos].id, A[pos].d * mu[j]); } ans[Q[i].id] = calc(Q[i].n, Q[i].m);
}
for(int i = 1; i <= T; i++) printf("%d\n", ans[i] & 2147483647);
return 0;
}

题解【bzoj3529 [SDOI2014]数表】的更多相关文章

  1. BZOJ3529 [Sdoi2014]数表 【莫比乌斯反演】

    3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2151 Solved: 1080 [Submit][Status ...

  2. [bzoj3529][Sdoi2014]数表_树状数组_莫比乌斯反演

    数表 bzoj-3529 Sdoi-2014 题目大意:n*m的数表,第i行第j列的数是同时整除i和j的所有自然数之和.给定a,求数表中所有不超过a的和. 注释:$1\le n,m \le 10^5$ ...

  3. BZOJ3529 [Sdoi2014]数表【莫比乌斯反演】

    Description 有一张 n×m 的数表,其第 i 行第 j 列(1 <= i <= n, 1 <= j <= m)的数值为 能同时整除 i 和 j 的所有自然数之和.给 ...

  4. bzoj千题计划205:bzoj3529: [Sdoi2014]数表

    http://www.lydsy.com/JudgeOnline/problem.php?id=3529 有一张n*m的数表,其第i行第j列(1 < =i < =n,1 < =j & ...

  5. 莫比乌斯反演套路二--(n/d)(m/d)给提出来--BZOJ3529: [Sdoi2014]数表

    一个数表上第i行第j列表示能同时整除i和j的自然数,Q<=2e4个询问,每次问表上1<=x<=n,1<=y<=m区域内所有<=a的数之和.n,m<=1e5,a ...

  6. BZOJ3529: [Sdoi2014]数表(莫比乌斯反演,离线)

    Description 有一张 n×m 的数表,其第 i 行第 j 列(1 <= i <= n, 1 <= j <= m)的数值为 能同时整除 i 和 j 的所有自然数之和.给 ...

  7. BZOJ3529: [Sdoi2014]数表

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3529 挺恶心的数论TAT... 设f[i]是i的约数和,这个可以nln(n)扫出来. ans= ...

  8. bzoj3529: [Sdoi2014]数表 莫比乌斯反演

    题意:求\(\sum_{i=1}^n\sum_{j=1}^nf(gcd(i,j))(gcd(i,j)<=a),f(x)是x的因子和函数\) 先考虑没有限制的情况,考虑枚举gcd为x,那么有\(\ ...

  9. BZOJ3529: [Sdoi2014]数表(莫比乌斯反演 树状数组)

    题意 题目链接 Sol 首先不考虑\(a\)的限制 我们要求的是 \[\sum_{i = 1}^n \sum_{j = 1}^m \sigma(gcd(i, j))\] 用常规的套路可以化到这个形式 ...

随机推荐

  1. Python Tkinter-Event

    1.点击 from tkinter import * root=Tk() def printCoords(event): print(event.x,event.y) bt1=Button(root, ...

  2. HTML5+Bootstrap 学习笔记 4

    HTML5 <map> <area> 标签 <map> 标签定义客户端的图像映射.图像映射是带有可点击区域的图像. <area> 标签定义图像映射内部的 ...

  3. Python基础知识-09-函数

    python其他知识目录 1.函数介绍 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如pr ...

  4. socket编程 123

    1. 预备知识 一直以来很少看到有多少人使用php的socket模块来做一些事情,大概大家都把它定位在脚本语言的范畴内吧,但是其实php的socket模块可以做很多事情,包括做ftplist,http ...

  5. Scrum立会报告+燃尽图(十一月二十五日总第三十三次):展示博客

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2413 项目地址:https://git.coding.net/zhang ...

  6. Linux 下web开发环境搭建-jdk环境搭建

    Centos 7 附:windows 下jdk环境变量 CLASSPATH .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools ...

  7. 寒假c++学习计划

    课程选择 概览 清华大学 C++语言程序设计基础 深入学习 清华大学 C++语言程序设计进阶 (2015年秋) 理由 清华大学郑莉老师的课浅显易懂,很适合我这种小白,再加上学习过c语言理解c++基础并 ...

  8. 软工实践第八次作业(课堂实战)- 项目UML设计(第五组)

    本次作业博客 团队信息 队名:起床一起肝活队 原组长: 白晨曦(101) 原组员: 李麒 (123) 陈德斌(104) 何裕捷(214) 黄培鑫(217) 王焕仁(233) 林志华(128) 乐忠豪( ...

  9. MDL

    1 先是mdl的数据结构. 2 下面根据用法逐步的讲解mdl数据结构的含义:一般用法,先是 IoAllocateMdl :原型为: 最常用的是VirtualAddress和Length.把自己的Non ...

  10. Windows下基于http的git服务器搭建-gitstack

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Windows下基于http的git服务器搭建-gitstack     本文地址:http: ...