P6810 「MCOI-02」Convex Hull 凸包
一句话题意:
求出 \(\displaystyle\sum_{i=1}^{n}\sum_{j=1}^{m}\tau(i)\tau(j)\tau(gcd(i,j))\)
前置知识
\(dirirchlet\) 卷积
这里我们只需要了解他的一个性质, \(\tau * \mu = \epsilon\), 具体证明如下:
\(\tau = 1 * 1\)
\(\epsilon = \mu * 1\)
对于第一个柿子,两边同时卷上一个 \(\mu\) 变成:
\(\tau * \mu = 1 * 1 * \mu\)
\(\tau * \mu = 1 * \epsilon = \epsilon\)
2.线性筛约数个数
首先,我们对一个数有唯一分解定理:\(p = p_1^{k_1} \times p_2^{k2} \cdots p_n ^{kn}\)
那么这个数的约数个数可以写为 \(\prod (k_i+1)\) (这小学知识啦)。
我们维护两个数组 \(g[i]\) 表示 \(i\) 的最小质因子的次数, \(t[i]\) 表示 \(i\) 的约数个数和。
对于 质数 \(p\) 则有 \(g[p] = 1, t[p] = 2\)
对于不是质数的数 \(n\) 我们在筛的时候会在 \(i \times p\) 的时候筛到他。
若 \(i \bmod p == 0\) 表明 \(p\) 是 \(n\) 的最小质因子 ,则有 \(g[n] = 1\), \(f[n] =\) \(f[i] \times (g[n]+1) \over {g[i]+1}\)
若 \(i 和 p 互质\) 可以利用积性函数的性质求解,则有 \(g[n] = g[i] + 1\) \(f[n] = f[i] * f[p]\) , 也可以写成 \(f[n] = f[i] * 2\)
Code:
g[1] = 1; t[1] = 1;
for(int i = 2; i <= N-5; i++)
{
if(!check[i])
{
prime[++tot] = i;
g[i] = 1;
t[i] = 2;
}
for(int j = 1; j <= tot && i * prime[j] <= N-5; j++)
{
check[i * prime[j]] = 1;
if(i % prime[j] == 0)
{
g[i * prime[j]] = g[i] + 1;
t[i * prime[j]] = t[i] * (g[i * prime[j]] + 1) / (g[i] + 1);
break;
}
else
{
g[i * prime[j]] = 1;
t[i * prime[j]] = t[i] * t[prime[j]];
}
}
}
题解
比较难的懵逼乌斯反演题。
首先,我们还是按照套路先枚举一个 \(d\) 来变成:
\(\displaystyle\sum_{d=1}^{n}\tau(d) \sum_{i=1}^{n} \sum_{j=1}^{m}\tau(i)\tau(j)[gcd(i,j) == d]\)
后面那两个求和柿子可以提出一个 \(d\) 出来变成:
\(\displaystyle\sum_{d=1}^{n}\tau(d) \sum_{i=1}^{n\over d} \sum_{j=1}^{m\over d}\tau(i \times d)\tau(j \times d)[gcd(i,j) == 1]\)
根据莫比乌斯反演,我们可以得到一个等式:
\([gc(i,j) == 1] = \displaystyle\sum_{p\mid i,p\mid j} \mu(p)\)
把这个等式代回原式有:
\(\displaystyle\sum_{d=1}^{n}\tau(d)\sum_{i=1}^{n\over d}\sum_{j=1}^{m \over d}\tau(i \times d)\tau(j\times d) \sum_{p\mid i p\mid j} \mu(p)\)
先枚举一下 \(p\) 变成:
\(\displaystyle\sum_{d=1}^{n}\tau(d)\sum_{p=1}^{n\over d} \mu(p)\sum_{i=1}^{n\over d} \tau(i \times d)[p \mid i]\sum_{j=1}^{m \over d}\tau(j \times d) [p \mid j]\)
后面的那个求和柿子可以变成:
\(\displaystyle\sum_{d=1}^{n}\tau(d)\sum_{p=1}^{n\over d} \mu(p)\sum_{i=1}^{n\over {dp}} \tau(i \times d p) \sum_{j=1}^{m \over {dp}}\tau(j \times dp)\)
设 \(Q = dp\) 则 \(p = {Q \over d}\),柿子可以写成:
\(\displaystyle\sum_{d=1}^{n}\tau(d)\sum_{Q=1}^{n}\mu({Q\over d})\sum_{i=1}^{n\over Q}\sum_{j = 1}^{m \over Q}\tau(iQ)\tau(jQ)\)
改变一下枚举顺序,先枚举一下 \(Q\) 则有:
\(\displaystyle\sum_{Q=1}^{n}\sum_{d\mid Q}^{n} \tau(d)\mu({Q\over d})\sum_{i=1}^{n\over Q}\sum_{j=1}^{m\over Q}\tau(iQ)\tau(jQ)\)
中间的这个 \(\displaystyle\sum_{d\mid Q}^{n}\tau(d)\mu({Q\over d})\) 柿子,利用我们前置知识里的一个性质:\(\tau * \mu = e\) 也就是这个柿子恒等于 \(1\)
我们的柿子就可以变为:
\(\displaystyle\sum_{Q=1}^{n}\sum_{i=1}^{n\over Q}\sum_{j=1}^{m\over Q} \tau(iQ)\tau(jQ)\)
这个直接枚举的复杂度跟定会爆的,我们还要考虑优化。
我们可以对于每个 \(Q\) 先把他后面的两个柿子先预处理出来,之后我们在枚举每个 \(Q\) 时可以直接得到这个 \(Q\) 的·贡献。
据说还可以用 \(dirichlet\) 后缀和优化,然鹅我并不会。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 2e6+10;
int n,m,p,tot;
int t[N],g[N],prime[N],sum1[N],sum2[N];
bool check[N];
inline int read()
{
int s = 0,w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s =s * 10+ch - '0'; ch = getchar();}
return s * w;
}
void YYCH()
{
g[1] = 1; t[1] = 1;
for(int i = 2; i <= N-5; i++)//预处理出每个数的约数个数
{
if(!check[i])
{
prime[++tot] = i;
g[i] = 1;
t[i] = 2;
}
for(int j = 1; j <= tot && i * prime[j] <= N-5; j++)
{
check[i * prime[j]] = 1;
if(i % prime[j] == 0)
{
g[i * prime[j]] = g[i] + 1;
t[i * prime[j]] = t[i] * (g[i * prime[j]] + 1) / (g[i] + 1);
break;
}
else
{
g[i * prime[j]] = 1;
t[i * prime[j]] = t[i] * t[prime[j]];
}
}
}
}
int slove(int n,int m)
{
YYCH();
int res = 0;
for(int d = 1; d <= n; d++)//预处理出每个 Q 的贡献
{
for(int j = 1; j <= n/d; j++)
{
sum1[d] = (sum1[d] + t[j * d]) % p;
}
}
for(int d = 1; d <= m; d++)
{
for(int j = 1; j <= m/d; j++)
{
sum2[d] = (sum2[d] + t[j * d]) % p;
}
}
for(int d = 1; d <= n; d++)//枚举每个Q
{
res = (res + 1LL * sum1[d] * sum2[d] % p) % p;//计算答案
}
return res % p;
}
int main()
{
n = read(); m = read(); p = read();
if(n > m) swap(n,m);
printf("%d\n",slove(n,m));
return 0;
}
话说,这题感觉难度有点低,应该是紫题吧,毕竟最后的 \(dirilect\) 后缀和优化的模板题都是紫的
P6810 「MCOI-02」Convex Hull 凸包的更多相关文章
- 【题解】「MCOI-02」Convex Hull 凸包
题目戳我 \(\text{Solution:}\) \[\sum_{i=1}^n \sum_{j=1}^n \rho(i)\rho(j)\rho(\gcd(i,j)) \] \[=\sum_{d=1} ...
- 【题解】「UVA681」Convex Hull Finding
更改了一下程序的错误. Translation 找出凸包,然后逆时针输出每个点,测试数据中没有相邻的边是共线的.多测. Solution 首先推销一下作者的笔记 由此进入>>> ( ...
- 【题解】「UVA11626」Convex Hull
凸包模板题. 之前写过拿 Graham 算法求凸包的,为了不重复/多学点知识,那这次拿 Andrew 算法求凸包吧qaq *此文章所有图片均为作者手画. Andrew 算法 假设我们有这些点: 首先把 ...
- [GYM 100492A] Average Convex Hull 凸包好题
大致题意: 给出一个点集,其中有一个点有相同的几率会被删除,求删除之后的点集够成的凸包上的点的平均数. 首先看到题目,可以考虑枚举删除的点,将其凸包上前后两点以及两点间凸包内所有点构建凸包,因为凸包内 ...
- Opencv Convex Hull (凸包)
#include <iostream>#include <opencv2/opencv.hpp> using namespace std;using namespace cv; ...
- 2.2 convex hull凸包
1.定义:一组平面上的点,求一个包含所有点的最小的凸多边形,就是凸包问题. 利用编程解决凸包问题,应该得到一组逆时针的顶点的顺序集合,在边上但不是顶点,则不包含在集合里. 2.机械的方法:将点所在的位 ...
- 凸包(Convex Hull)构造算法——Graham扫描法
凸包(Convex Hull) 在图形学中,凸包是一个非常重要的概念.简明的说,在平面中给出N个点,找出一个由其中某些点作为顶点组成的凸多边形,恰好能围住所有的N个点. 这十分像是在一块木板上钉了N个 ...
- OpenCV入门之寻找图像的凸包(convex hull)
介绍 凸包(Convex Hull)是一个计算几何(图形学)中的概念,它的严格的数学定义为:在一个向量空间V中,对于给定集合X,所有包含X的凸集的交集S被称为X的凸包. 在图像处理过程中,我们 ...
- Monotone Chain Convex Hull(单调链凸包)
Monotone Chain Convex Hull(单调链凸包)算法伪代码: //输入:一个在平面上的点集P //点集 P 按 先x后y 的递增排序 //m 表示共a[i=0...m]个点,ans为 ...
随机推荐
- Matrix4x4
Unity3D开发之Matrix4x4矩阵变换 https://www.cnblogs.com/hewei2012/p/4190282.html Matrix4x4 4x4矩阵 http://wiki ...
- SQL SERVER管理维护计划错误,备份错误,1053/3041/错误18204,严重性16,状态1
在sqlserv2008/2012里设置了管理-维护计划-备份计划,前些天遇到报错-1053/3041/错误18204,严重性16,状态1等:分享下解决方法. 1.在服务器执行任务报错 2.解决办法 ...
- VMware Workstation Pro15安装路径、修复等问题
我的VMware Worstation 昨晚报错,无法打开虚拟机,VMware Authorization Services 也无法启动,于是卸载重装,结果仍然无法启动VMware Authoriza ...
- 使用Json-lib将对象和Json互转
工程下载地址: https://files.cnblogs.com/files/xiandedanteng/jsonSample20200308.rar Depenency: <!-- 使用js ...
- URL 去重的 6 种方案!(附详细实现代码)
URL 去重在我们日常工作中和面试中很常遇到,比如这些: 可以看出,包括阿里,网易云.优酷.作业帮等知名互联网公司都出现过类似的面试题,而且和 URL 去重比较类似的,如 IP 黑/白名单判断等也经常 ...
- 零基础一分钟入门Python
这篇文章面向所有想学python的小伙伴(甚至你从没听过编程),这篇文章将会带你以最快的速度入门python.赶快上车,时间来不及了... 一,下载和安装python 1.下载: 1.1 python ...
- python pickle库
一.简介: 将文本信息转变为二进制数据流存储在一个文件中,便于下次使用. 二.常用函数: dump(object, file, protocol=None) 必填参数 obj 表示将要封装的对象 必填 ...
- JDK1.7之前的Bug之静态代码块
程序的主入口是main方法,但是在jdk1.7之前,可以没有main方法也一样能运行,很是不可思议,到底是什么原因呢?,大家都知道在类中定义了静态代码块的话,是首先执行代码块里的语句的,如果把静态代码 ...
- IDEA创建新空项目
IDEA创建新空项目 File -> New -> Project -> Empty Project -> 然后OK 这个是什么都不能做的,然后我们创建Module. File ...
- 来讲讲你对ThreadLocal的理解
前言 面试的时候被问到ThreadLocal的相关知识,没有回答好(奶奶的,现在感觉问啥都能被问倒),所以我决定先解决这几次面试中都遇到的高频问题,把这几个硬骨头都能理解的透彻的说出来了,感觉最起码不 ...