[BZOJ3529][Sdoi2014]数表

试题描述

有一张N×m的数表,其第i行第j列(1 < =i < =n,1 < =j < =m)的数值为能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。

输入

输入包含多组数据。
输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。

输出

对每组数据,输出一行一个整数,表示答案模2^31的值。

输入示例

2
4 4 3
10 10 5

输出示例

20
148

数据规模及约定

1 < =N.m < =10^5  , 1 < =Q < =2×10^4

题解

我们设 f(i) 表示 i 的所有约数和,g(i) 表示 x∈[1, n],y∈[1, m] 范围内有多少对 (x, y) 使得 gcd(x, y) = i。

那么 f(i) 可以线性筛求出,g(i) 可以莫比乌斯反演得出。

令 T = id,并交换求和顺序,得到

受到前面题的启发,我们可以用调和级数的复杂度求得所有的 F(T)。

那么现在还要求 f(i) ≤ a,咋办?

离线,把询问按照 a 的大小排序,按照 f(i) 的大小顺序依次插入,每次更新 F(T),然后树状数组更新 sum(n)。

查询的时候,按照 [n / T][m / T] 分类计算,总复杂度 O(n log2n + n sqrt(n) logn)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {if(Head == Tail) {int l = fread(buffer, 1, BufferSize, stdin);Tail = (Head = buffer) + l;}return *Head++;
}
int read() {int x = 0, f = 1; char c = Getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }return x * f;
}#define maxn 100010const int MOD = 2147483647;
int prime[maxn], cp, mu[maxn], smu[maxn], remain[maxn], f[maxn], Ord[maxn];
bool vis[maxn];
bool cmp(int a, int b) { return f[a] < f[b]; }
void init() {mu[1] = 1; f[1] = 1;for(int i = 2; i < maxn; i++) {if(!vis[i]) prime[++cp] = i, mu[i] = -1, f[i] = 1 + i, remain[i] = 1;for(int j = 1; i * prime[j] < maxn && j <= cp; j++) {vis[i*prime[j]] = 1;if(i % prime[j] == 0) {mu[i*prime[j]] = 0;f[i*prime[j]] = f[i] + f[remain[i]] * (i / remain[i] * prime[j]);remain[i*prime[j]] = remain[i];break;}mu[i*prime[j]] = -mu[i];f[i*prime[j]] = f[i] * (prime[j] + 1);remain[i*prime[j]] = i;}smu[i] = smu[i-1] + mu[i];}for(int i = 1; i < maxn; i++) Ord[i] = i;sort(Ord + 1, Ord + maxn, cmp);return ;
}struct Que {int n, m, a, id;Que() {}Que(int _1, int _2, int _3, int _4): n(_1), m(_2), a(_3), id(_4) {}bool operator < (const Que& t) const { return a < t.a; }
} qs[maxn];
int Ans[maxn];int S[maxn];
void Add(int x, int v) {for(; x < maxn; x += x & -x) S[x] += v;return ;
}
int Sum(int x) {int ans = 0;for(; x; x -= x & -x) ans += S[x];return ans;
}int main() {init();int T = read();for(int i = 1; i <= T; i++) {int n = read(), m = read(), a = read();qs[i] = Que(n, m, a, i);}sort(qs + 1, qs + T + 1);int j = 1;for(int q = 1; q <= T; q++) {while(j < maxn && f[Ord[j]] <= qs[q].a) {for(int d = 1; Ord[j] * d < maxn; d++) Add(Ord[j] * d, f[Ord[j]] * mu[d]);j++;}int n = qs[q].n, m = qs[q].m; if(n > m) swap(n, m);for(int i = 1, lst; i <= n; i = lst + 1) {lst = min(n / (n / i), m / (m / i));Ans[qs[q].id] += (n / i) * (m / i) * (Sum(lst) - Sum(i - 1));}}for(int i = 1; i <= T; i++) printf("%d\n", Ans[i] & MOD);return 0;
}

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/7109393.html

[BZOJ3529][Sdoi2014]数表相关推荐

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

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

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

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

  3. bzoj3529: [Sdoi2014]数表

    %%%Po姐姐 https://wenku.baidu.com/view/fbec9c63ba1aa8114431d9ac.html [题意] 见原题 [题解] 一个数对(x,y)的公约数必定是其最大 ...

  4. (每日一题)P3312 [SDOI2014]数表(经典莫比乌斯反演 + 树状数组维护离线询问)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 每日一题(莫反 / 多项式 / 母函数 / 群论) 2021.4.11 莫反 P3312 [SDOI2 ...

  5. BZOJ 3529: [Sdoi2014]数表

    二次联通门 : BZOJ 3529: [Sdoi2014]数表 Latex的公式写起来略麻烦... 设$\LARGE F(x)=\sum_{d|x} \lfloor \dfrac xd \rfloor ...

  6. P3312 [SDOI2014]数表(离线 + 树状数组前缀和优化)

    P3312 [SDOI2014]数表 推式子 ∑i=1n∑j=1mσ(gcd(i,j))∑d=1nσ(d)∑i=1nd∑j=1md[gcd(i,,j)==1]∑d=1nσ(d)∑d=1ndμ(k)nk ...

  7. BZOJ 3529: [Sdoi2014]数表 莫比乌斯

    3529: [Sdoi2014]数表 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 1879  Solved: 949 [Submit][Statu ...

  8. 3529: [Sdoi2014]数表 - BZOJ

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

  9. 【BZOJ3529】数表,莫比乌斯反演+BIT

    传送门 思路: 复习一下莫比乌斯反演 好像是数论入门题,然后我做了近一天-- 式子是这么化没错 n≤mn≤m ∑i=1n∑j=1m[σ(gcd(i,j))≤a]σ(gcd(i,j)) \sum^n_{ ...

最新文章

  1. pandas删除dataframe中行内容全是0的数据行(remove rows with all zeros in dataframe)
  2. Java中float类型精度问题
  3. nodejs http.get 方法可以 request 不行
  4. 使用dokcer搭建个人博客网站
  5. python拷贝文件函数_Python Set集合,函数,深入拷贝,浅入拷贝,文件处理
  6. VTK:小部件之CheckerboardWidget
  7. html5生日时间怎么写代码,用JavaScript写得比较日期,计算生日的函数,
  8. android学习者优秀网址推荐
  9. 德州python培训_人工智能在多人桌德州扑克比赛中战胜世界顶尖选手
  10. freebsd 安装教程
  11. 如何避免文件被删无法找回的尴尬?
  12. 2010罗森伯格HDCS®综合布线分布线销商大会顺利召开
  13. 关于计算机应用基础论文,关于计算机应用基础论文
  14. WDM驱动安装和卸载
  15. 圣思园 java_圣思园Java8新特性及实战视频教程 下载
  16. 分享一个简单唯美的404页
  17. 2019JAVA面试题附答案-精心整理-很全面面试大大节省时间
  18. 英语中的I(我)为什么要大写?
  19. Java类型转换(自动类型转换+强制类型转换)
  20. 通过Python分析2020年全年微博热搜数据

热门文章

  1. 并发编程---线程queue---进程池线程池---异部调用(回调机制)
  2. 云通讯短信验证码实例
  3. Hitting refresh on my career(译)----重新定义我的事业
  4. zabbix3.2监控
  5. 在fedora下面安装ftp服务器
  6. C语言 · 未名湖边的烦恼
  7. ios多线程 -- NSOperation 简介
  8. 2000错误信息:MMC创建无法管理单元。
  9. web策略类游戏开发(四)一个可以承载万人在线的架构
  10. C语言中输入输出格式控制