此题是 2018 年 ICPC Asia Beijing Regional Contest 的 C 题。

题目大意

求斜边长度不超过 $n$($ n \le 10^9$) 的勾股数的数量。不计两直角边的顺序,即勾股数 $(a, b, c)$ 和 $(b, a, c)$ 视作同一组。

分析

这是一道颇为经典的计数问题。

请先阅读维基百科上的 Pythagorean triple 条目。

设斜边为 $n$ 的勾股数有 $f(n)$ 个。又设斜边为 $n$ 的本原勾股数有 $g(n)$ 个。于是有

$ f(n) = \sum_{d \mid n} g(d)$ 。

令 $F$ 为 $f$ 的前缀和,令 $G$ 为 $g$ 的前缀和。有

\begin{aligned}

F(n) &= \sum_{i = 1}^{n} f(n) \\

&= \sum_{i = 1}^{n} \sum_{d \mid i} g(d) \\

&= \sum_{i = 1}^{n} G(\floor{n / i})

\end{aligned}

根据 $G$ 的定义,有

\begin{aligned}

G(n) &= \sum_{i = 1}^{n} g(i) \\

&=\sum_{\substack{1 \le x \le n \\ x \text{ is odd} } } \sum_{\substack{1 \le y \le n \\ y \text{ is even}}} [x^2 + y^2 \le n] [\gcd(x, y) = 1] \\

&= \frac{1}{2} \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] [\gcd(x, y) = 1]

\end{aligned}

\begin{aligned}

& \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] [\gcd(x, y) = 1] \\

&= \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] \sum_{d \mid \gcd(x, y)} \mu(d) \\

&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{1 \le x \le n } \sum_{1 \le y \le n } - \sum_{\substack{1 \le x \le n \\ x \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [x^2 + y^2 \le n] [d \mid x] [d \mid y] \\

&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le n/d } \sum_{1 \le y \le n } - \sum_{\substack{1 \le i \le n/d \\ di \text{ is odd}} } \sum_{\substack{1 \le y \le n \\ y \text{ is odd}} } \right) [(id)^2 + y^2 \le n] [d \mid y] \\

&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le \sqrt{n}/d } \sum_{1 \le j \le \sqrt{n-(id)^2}/d } - \sum_{\substack{1 \le i \le \sqrt{n}/d \\ di \text{ is odd}} } \sum_{\substack{1 \le j \le \sqrt{n-(id)^2}/d \\ dj \text{ is odd}} } \right) 1 \\

&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le \sqrt{n}/d } \floor{ \frac{\sqrt{n-(id)^2}}{d} } - [d \text{ is odd}] \sum_{\substack{1 \le i \le \sqrt{n}/d \\ i \text{ is odd}} } \sum_{\substack{1 \le j \le \sqrt{n-(id)^2}/d \\ j \text{ is odd}} } 1 \right) \\

&= \sum_{1\le d \le \sqrt{n/2}} \mu(d) \left(\sum_{ 1 \le i \le \sqrt{n}/d } \floor{ \frac{\sqrt{n-(id)^2}}{d} } - [d \text{ is odd}] \sum_{\substack{1 \le i \le \sqrt{n}/d \\ i \text{ is odd}} } \floor{\frac{\frac{\sqrt{n-(id)^2}}{d} + 1}{2}} \right)

\end{aligned}

TODO:复杂度分析。

Implementation

预处理 $G$ 的前 2000 万项。

注意:代码不完整。

int main() {
FAST_READ
cout << fixed << setprecision(1);
#ifdef LOCAL
ifstream in("main.in");
cin.rdbuf(in.rdbuf());
#endif const int nax = 1e9 + 1;
// println(nax);
const int pre_n = 2e7;
vl pre_G(pre_n + 1); // pre-calculate some items of G
const int max_v = sqrt(pre_n); stp(i, 1, max_v + 1, 2) {
const int i2 = i * i;
const int max_j = sqrt(pre_n - i2);
stp (j, 2, max_j + 1, 2) {
if (__gcd(i, j) == 1) {
pre_G[i2 + j * j]++;
}
}
} rng (i, 1, pre_n + 1) {
pre_G[i] += pre_G[i - 1];
} const int max_d = sqrt(nax/2); const auto mu = get_mu(max_d); auto G = [&mu, &pre_G, pre_n](int n) { // # of primitive Pythagorean triples with c <= n
if (n <= pre_n) return pre_G[n];
ll ans = 0;
const int max_gcd = sqrt(n / 2);
const int tmp = (int)sqrt(n);
rng (d, 1, max_gcd + 1) {
ll sum = 0;
const int max_i = tmp / d;
for (int i = 1; i <= max_i; ) {
const int arg = int(sqrt(n - sq(i*d))) / d;
const int j = int(sqrt(n - sq(arg * d))) / d;
sum += (j - i + 1) * arg;
if (d & 1) {
sum -= (j - i + 1 + (i & 1)) / 2 * ((arg + 1) / 2);
}
i = j + 1;
}
ans += sum * mu[d];
}
return ans / 2;
}; auto F = [&](int n) { // # of Pythagorean triples with c <= n
ll ans = 0;
for (int i = 1; i <= n; ) {
int arg = n / i;
int j = n / arg;
ans += 1LL * (j - i + 1) * G(arg);
i = j + 1;
}
return ans;
}; int T; scan(T); rep (T) {
int n; scan(n);
println(F(n));
} #ifdef LOCAL
cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}

hihoCoder #1872 : Pythagorean triple的更多相关文章

  1. Codeforces Round #368 (Div. 2) C. Pythagorean Triples(数学)

    Pythagorean Triples 题目链接: http://codeforces.com/contest/707/problem/C Description Katya studies in a ...

  2. Pythagorean Triples

    Pythagorean Triples time limit per test 1 second memory limit per test 256 megabytes input standard ...

  3. codeforces-707 C. Pythagorean Triples

    C. Pythagorean Triples time limit per test 1 second memory limit per test 256 megabytes input standa ...

  4. Pythagorean Triples 707C

    Katya studies in a fifth grade. Recently her class studied right triangles and the Pythagorean theor ...

  5. Codeforces Round #368 (Div. 2) C. Pythagorean Triples 数学

    C. Pythagorean Triples 题目连接: http://www.codeforces.com/contest/707/problem/C Description Katya studi ...

  6. Pythagorean Triples毕达哥斯拉三角(数学思维+构造)

    Description Katya studies in a fifth grade. Recently her class studied right triangles and the Pytha ...

  7. codeforces707C:Pythagorean Triples

    Description Katya studies in a fifth grade. Recently her class studied right triangles and the Pytha ...

  8. codeforces 707C C. Pythagorean Triples(数学)

    题目链接: C. Pythagorean Triples time limit per test 1 second memory limit per test 256 megabytes input ...

  9. Codeforces Round #368 (Div. 2) C

    Description Katya studies in a fifth grade. Recently her class studied right triangles and the Pytha ...

随机推荐

  1. loushang框架的开发中关于BSP的使用,将写好的功能模块部署到主页界面结构上

    前言: 当我们已经开发好相应的模块或者功能的时候,需要将这个功能部署在index主页上作为可点击直接使用的模块,而不是每次需要去浏览对应的url地址. 这时候就需要运用到L5的BSP. 作为刚刚入门l ...

  2. 发布django项目

    supervisor需要用到的技术 1. nginx反向代理 2. nginx负载均衡 3. uwsgi 4. supervisor 5. virtualenv 安装nginx 详情参考 https: ...

  3. ReentrantLock详解

    ReentrantLock概述 ReentrantLock是Lock接口的实现类,可以手动的对某一段进行加锁.ReentrantLock可重入锁,具有可重入性,并且支持可中断锁.其内部对锁的控制有两种 ...

  4. JavaSE 第二次学习随笔(三)

    * 常见异常 * 数组越界异常 * 空指针异常 * * * 特点: 当程序出现异常的时候, 程序会打印异常信息并中断程序 * 所以当同时出现多个异常的时候只能执行第一个, 后边的用不到 * * 单异常 ...

  5. Hadoop(6)-HDFS的shell操作

    1.基本语法 使用 hadoop fs 具体命令   或者   hdfs dfs 具体命令 hadoop命令的shell源码 hdfs命令的shell源码 由此可见,这两个命令最后都是执行的一个jav ...

  6. MR执行流程

    1.Map任务处理 1.1 读取HDFS中的文件.每一行解析成一个<k,v>.每一个键值对调用一次map函数. <0,hello you>   <10,hello me& ...

  7. 8.Mongodb备份与恢复

    1.备份 语法 mongodump -h dbhost -d dbname -o dbdirectory -h:服务器地址,也可以指定端口号 -d:需要备份的数据库名称 -o:备份的数据存放位置,此目 ...

  8. P1823 音乐会的等待(单调栈)

    P1823 音乐会的等待 题目描述 N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没有人比A或B高,那么 ...

  9. Mysql自学笔记

    SQL(strucut query language) DDL (数据库定义语言)DML (数据库操作语言)DCL (数据库的控制语言)DTL (数据库的高级语言)查看版本的函数select vers ...

  10. Java - 问题集 - linux下,jar: command not found

    linux下的找不到jar命令解决方法如下: 1. 确认jdk是否已安装 2. 检查jdk环境变量是否已设置,并且确认该设置已生效 3. 1,2两步均正常时,建立jar的软链接 # cd /usr/b ...