HDU 5528 Count a * b 欧拉函数
题意:
定义函数\(f(n)\)为\(i \cdot j \not\equiv 0 \; (mod \; n)\)的数对\((i,j)\)的个数\((0 \leq i,j \leq n)\)
\(g(n)=\sum_{d|n}f(d)\),求\(g(n) \; mod \; 2^{64}\),其中\(1 \leq n \leq 10^9\)
仰慕叉老师手推公式
分析:
计算\(f(n)\)
\(f(n)\)不容易计算,但可以计算它的反面,也就是计算满足\(ij \equiv 0 \; (mod \; n)\)的数对\((i,j)\)的个数。
为了方便计算,对\(i,j\)的范围稍作改动,\(1 \leq i,j \leq n\),这不会影响最终计算结果。
\(i \cdot j\)是\(n\)的整数倍,也就是\(n\)被分到了这里面。
不妨设\(i=ax,j=by\),其中\(ab=n\)。我们可以枚举\(a\)来统计答案,但是这样有重复计算。
比如\((3 \cdot 2) \cdot (2 \cdot 1) = (6 \cdot 1) \cdot (2 \cdot 1) = 6 \cdot 2\),这样数对\((6, 2)\)在\(a=3\)和\(a=6\)时被计算了两次。
所以计数时我们规定,数对\((i,j)\)只会在\(a\)最大的时候被计算,所以有\(gcd(b,x)=1\)成立。
答案为\(\sum\limits_{a|n} \sum\limits_{1 \leq x \leq \frac{n}{a}}[gcd(x,b)=1] \cdot \frac{n}{b}=\sum\limits_{a|n}a \phi(\frac{n}{a})\)
计算\(g(n)\)
根据题中给的关系,得到\(g(n)=\sum\limits_{m|n}(m^2-f(m))=\sum\limits_{m|n}(m^2-\sum\limits_{d|m}d \phi(\frac{m}{d}))\)
继续化简后面那部分,\(\sum\limits_{m|n}\sum\limits_{d|m}d \phi(\frac{m}{d})\)交换求和顺序,得到\(\sum\limits_{d|n}d\sum\limits_{\frac{m}{d}|\frac{n}{d}}\phi(\frac{m}{d})\)
由于\(\sum\limits_{d|n} \phi(d)=n\),所以得到\(\sum\limits_{d|n}d \cdot \frac{n}{d}=n\sum\limits_{d|n}1=n \sigma(n)\)。其中\(\sigma(n)\)为\(n\)的约数的个数。
\(\sigma(n)\)可以这样计算:
首先将\(n\)质因数分解为\(\prod\limits_{i=1}^{r}p_{i}^{e_i}\),这样\(\sigma(n)=\prod\limits_{i=1}^{r}(e_i+1)\)。
因为我们已经将\(n\)分解,所以计算前面那部分的时候不要在\(\sqrt{n}\)内枚举\(n\)的约数,会超时的。要根据分解出来的结果直接枚举。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 32000 + 10;
int pcnt, prime[maxn];
bool vis[maxn];
void preprocess() {
for(int i = 2; i < maxn; i++) {
if(!vis[i]) prime[pcnt++] = i;
for(int j = 0; j < pcnt && i * prime[j] < maxn; j++) {
vis[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
}
int tot, p[maxn], e[maxn];
unsigned long long ans;
void dfs(int d, unsigned long long product) {
if(d == tot) {
ans += product * product;
return ;
}
dfs(d + 1, product);
for(int i = 1; i <= e[d]; i++) {
product *= p[d];
dfs(d + 1, product);
}
}
int main()
{
preprocess();
int T; scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
int t = n;
tot = 0;
for(int i = 0; i < pcnt && prime[i] * prime[i] <= n; i++) {
if(t % prime[i] == 0) {
p[tot] = prime[i];
e[tot] = 0;
while(t % prime[i] == 0) {
t /= prime[i];
e[tot]++;
}
tot++;
}
}
if(t > 1) { p[tot] = t; e[tot++] = 1; }
unsigned long long tmp = 1;
for(int i = 0; i < tot; i++) tmp = tmp * (e[i] + 1);
tmp *= n;
ans = 0;
dfs(0, 1);
ans -= tmp;
printf("%llu\n", ans);
}
return 0;
}
HDU 5528 Count a * b 欧拉函数的更多相关文章
- HDU 4483 Lattice triangle(欧拉函数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4483 题意:给出一个(n+1)*(n+1)的格子.在这个格子中存在多少个三角形? 思路:反着想,所有情 ...
- hdu 2824 The Euler function(欧拉函数)
题目链接:hdu 2824 The Euler function 题意: 让你求一段区间的欧拉函数值. 题解: 直接上板子. 推导过程: 定义:对于正整数n,φ(n)是小于或等于n的正整数中,与n互质 ...
- HDU - 2824 The Euler function 欧拉函数筛 模板
HDU - 2824 题意: 求[a,b]间的欧拉函数和.这道题卡内存,只能开一个数组. 思路: ϕ(n) = n * (p-1)/p * ... 可利用线性筛法求出所有ϕ(n) . #include ...
- HDU 4002 Find the maximum(欧拉函数)
题目链接 猜了一个结论,题面跟欧拉函数有关系. import java.util.*; import java.math.*; import java.text.*; import java.io.* ...
- HDU 1695 GCD (容斥原理+欧拉函数)
题目链接 题意 : 从[a,b]中找一个x,[c,d]中找一个y,要求GCD(x,y)= k.求满足这样条件的(x,y)的对数.(3,5)和(5,3)视为一组样例 . 思路 :要求满足GCD(x,y) ...
- HDU 3501 Calculation 2 (欧拉函数)
题目链接 题意 : 求小于n的数中与n不互质的所有数字之和. 思路 : 欧拉函数求的是小于等于n的数中与n互质的数个数,这个题的话,先把所有的数字之和求出来,再减掉欧拉函数中所有质数之和(即为eula ...
- HDU 3501 Calculation 2(欧拉函数)
Calculation 2 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submi ...
- hdu 1695 GCD 容斥+欧拉函数
题目链接 求 $ x\in[1, a] , y \in [1, b] $ 内 \(gcd(x, y) = k\)的(x, y)的对数. 问题等价于$ x\in[1, a/k] , y \in [1, ...
- hdu 2824 The Euler function 欧拉函数打表
The Euler function Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
随机推荐
- c# 串口操作
public class CommPort : IDisposable { public string Port = ""; ///<summary> ///波特率96 ...
- 关于使用mybatis的分页插件问题
首先我需要导入架包 1.pagehelper 如果你是在mybatis中配置分页‘ 如下代码 <plugins> <plugin interceptor="com.gith ...
- npm使用快速的安装源(nrm)
安装 npm install nrm --global 使用 nrm ls 切换安装源 nrm use taobao 测速 nrm test npm 参考地址:http://codingdict.co ...
- 用Python完成根据日期计算是星期几
import datetime def week(year,month,day): someday=dayetime.date(year,month,day) result={ "0&quo ...
- java object默认的基本方法
java object默认的基本方法中没有copy(),含有如下9个方法: getClass(), hashCode(), equals(), clone(), toString(), notify ...
- sqlserver 查询某表的所有列名
select name + ',' from syscolumns where id = object_id('SEND_TALLY') AND name <> 'PICDATAS'
- 如何处理错误消息Please install the Linux kernel header files
Please install the Linux kernel "header" files matching the current kernel 当我启动minilkube时遇 ...
- Spark集群任务提交
1. 集群管理器 Spark当前支持三种集群管理方式 Standalone—Spark自带的一种集群管理方式,易于构建集群. Apache Mesos—通用的集群管理,可以在其上运行Hadoop Ma ...
- Trie入门讲解
我们常常用Trie(也叫前缀树)来保存字符串集合.如下图所示就是一个Trie. 上图表示的字符串集合为$\{a,to,tea,ted,ten,i,in,inn \}$,每个单词的结束位置对应一个“单词 ...
- 使用ErrorProvider组件验证文本框输入
实现效果: 知识运用: ErrorProvider组件的BlinkStyle属性 //指示错误图标的闪烁时间 public ErrorBlinkStyle BlinkStyle{ get;set; } ...