\(\color{#0066ff}{ 题目描述 }\)

由于出题人懒得写背景了,题目还是简单一点好。

输入一个整数n和一个整数p,你需要求出(\(\sum_{i=1}^n\sum_{j=1}^n ijgcd(i,j))~mod~p\),其中gcd(a,b)表示a与b的最大公约数。

\(\color{#0066ff}{输入格式}\)

一行两个整数p、n。

\(\color{#0066ff}{输出格式}\)

一行一个整数(\(\sum_{i=1}^n\sum_{j=1}^n ijgcd(i,j))~mod~p\)。

\(\color{#0066ff}{输入样例}\)

998244353 2000

\(\color{#0066ff}{输出样例}\)

883968974

\(\color{#0066ff}{数据范围与提示}\)

对于20%的数据,\(n \leq 1000\)。

对于30%的数据,\(n \leq 5000\)。

对于60%的数据,\(n \leq 10^6\),时限1s。

对于另外20%的数据,\(n \leq 10^9\),时限3s。

对于最后20%的数据,\(n \leq 10^{10}\),时限6s。

对于100%的数据,\(5 \times 10^8 \leq p \leq 1.1 \times 10^9\)且p为质数。

\(\color{#0066ff}{ 题解 }\)

这是一道神仙题qwq

开始推式子

题目要求

\[\sum_{i=1}^n\sum_{j=1}^n i*j*gcd(i,j)
\]

老规矩,枚举gcd

\[\sum_{d=1}^n\sum_{i=1}^n\sum_{j=1}^n [gcd(i,j)==d]i*j*d
\]

把d提出来

\[\sum_{d=1}^n d\sum_{i=1}^n\sum_{j=1}^n [gcd(i,j)==d]i*j
\]

后面把d弄出来

\[\sum_{d=1}^n d^3\sum_{i=1}^{\lfloor \frac n d \rfloor}\sum_{j=1}^{\lfloor \frac n d \rfloor} [gcd(i,j)==1]i*j
\]

利用\(\mu * i = e\)套进去

\[\sum_{d=1}^n d^3\sum_{i=1}^{\lfloor \frac n d \rfloor}\sum_{j=1}^{\lfloor \frac n d \rfloor} \sum_{k|gcd(i,j)} \mu(k)*i*j
\]

\[\sum_{d=1}^n d^3\sum_{k=1}^{\lfloor\frac n d \rfloor}\sum_{k|i} \sum_{k|j} \mu(k)*i*j
\]

改为枚举倍数

\[\sum_{d=1}^n d^3\sum_{k=1}^{\lfloor\frac n d \rfloor} \mu(k)*k^2\sum _{i=1}^{\lfloor\frac n {kd}\rfloor} \sum _{j=1}^{\lfloor\frac n {kd}\rfloor}i*j
\]

看到这个式子,大为欣喜,于是

\[令f(i)=\mu(i) * i^2, g(i)=i^2
\]

\[h(n)=\sum_{d|n} f(d)*g(\frac n d)
\]

\[h(n)=n^2\sum_{d|n} \mu(d)=e(n)
\]

于是以为这题切掉了?????

我TM。。数据范围尼玛\(10^9\)

\(how\ \ \ to \ \ \ O(\sqrt n ^2)\)

显然要继续往下推

某巨佬有一手,pd换q的操作(原式为kd换q)

于是,先将原式变为

\[\sum_{d=1}^n \sum_{k=1}^{\lfloor\frac n d \rfloor} \mu(k)*k^2 * d^3\sum _{i=1}^{\lfloor\frac n {kd}\rfloor} \sum _{j=1}^{\lfloor\frac n {kd}\rfloor}i*j
\]

考虑枚举q,那么里面的kd就可以提出来了

\[\sum_{q=1}^n q^2\sum_{k=1}^{\lfloor\frac n d \rfloor} \mu(k)* d\sum _{i=1}^{\lfloor\frac n {kd}\rfloor} \sum _{j=1}^{\lfloor\frac n {kd}\rfloor}i*j
\]

这里面的d有点突兀qwq

\[\sum_{q=1}^n q^2\sum_{k=1}^{\lfloor\frac n d \rfloor} \mu(k)* \frac q k \sum _{i=1}^{\lfloor\frac n {q}\rfloor}i \sum _{j=1}^{\lfloor\frac n {q}\rfloor}j
\]

上面的式子是有问题的,因为枚举的\(q=kd\),那么k应该是q的因子,所以要改一下枚举,同时后面的可以写成平方形式

\[\sum_{q=1}^n q^2\sum_{k|q} \mu(k)* \frac q k (\sum _{i=1}^{\lfloor\frac n {q}\rfloor}i)^2
\]

然后可以把q提出来

\[\sum_{q=1}^n q^3\sum_{k|q} \frac {\mu(k)} k (\sum _{i=1}^{\lfloor\frac n {q}\rfloor}i)^2
\]

然后因为有

\[\sum_{k|n} \frac {\mu(k)} k =\frac {\varphi(n)} {n}
\]

因此代回去

\[\sum_{q=1}^n q^3\frac {\varphi(q)} q (\sum _{i=1}^{\lfloor\frac n {q}\rfloor}i)^2
\]

卧槽,继续

\[\sum_{q=1}^n \varphi(q) * q^2 (\sum _{i=1}^{\lfloor\frac n {q}\rfloor}i)^2
\]

我Fuck, \(O(\sqrt n)\) 我就不信还过不了??

\[令f(i)=\varphi(i) * i^2, g(i)=i^2
\]

\[h(n)=\sum_{d|n} f(d)*g(\frac n d)=\sum_{d|n}\varphi(d)*n^2=n^3 ,因为(\varphi * i = id)
\]

杜教筛+数列分块就行了

注意各种取模,少一个都WAqwq

#include<bits/stdc++.h>
#define int long long
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 4e6 + 10;
LL pri[maxn], phi[maxn], tot, mod;
LL six;
std::map<int, LL> mp;
bool vis[maxn];
LL ksm(LL x, LL y) {
LL re = 1LL;
while(y) {
if(y & 1) re = re * x % mod;
x = x * x % mod;
y >>= 1;
}
return re;
}
void predoit() {
mod = in();
six = ksm(6, mod - 2);
phi[1] = 1;
for(int i = 2; i < maxn; i++) {
if(!vis[i]) pri[++tot] = i, phi[i] = i - 1;
for(int j = 1; j <= tot && (LL)i * pri[j] < maxn; j++) {
vis[i * pri[j]] = true;
if(i % pri[j] == 0) {
phi[i * pri[j]] = phi[i] * pri[j];
break;
}
else phi[i * pri[j]] = phi[i] * (pri[j] - 1);
}
}
for(LL i = 2; i < maxn; i++) phi[i] = phi[i] * (i * i % mod) % mod;
for(LL i = 2; i < maxn; i++) (phi[i] += phi[i - 1]) %= mod;
}
LL getpfh(LL x) {
x %= mod;
LL ans = x;
ans = (ans * (x + 1)) % mod;
ans = (ans * ((x << 1LL) + 1)) % mod;
return ans * six % mod;
}
LL getlf(LL n) {
n %= mod;
n = (n * (n + 1) >> 1) % mod;
return n * n % mod;
}
LL getphi(LL n) {
if(n < maxn) return phi[n];
if(mp.count(n)) return mp[n];
LL ans = getlf(n);
for(LL l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
LL tot1 = ((getpfh(r) - getpfh(l - 1)) % mod + mod) % mod;
tot1 = tot1 * getphi(n / l) % mod;
ans = ((ans - tot1) % mod + mod) % mod;
}
return mp[n] = ans;
}
LL getsum(LL x) {
x %= mod;
LL ans = (x * (x + 1) >> 1LL) % mod;
return ans * ans % mod;
}
void work(LL n) {
LL ans = 0;
for(LL l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
LL tot1 = ((getphi(r) - getphi(l - 1)) % mod + mod) % mod;
tot1 = (tot1 * getsum(n / l)) % mod;
ans = (ans + tot1) % mod;
}
printf("%lld", (ans % mod + mod) % mod);
}
signed main() {
predoit();
work(in());
return 0;
}

P3768 简单的数学题 杜教筛+推式子的更多相关文章

  1. luogu P3768 简单的数学题 杜教筛 + 欧拉反演 + 逆元

    求 $\sum_{i=1}^{n}\sum_{j=1}^{n}ijgcd(i,j)$   考虑欧拉反演: $\sum_{d|n}\varphi(d)=n$   $\Rightarrow \sum_{i ...

  2. P3768 简单的数学题 [杜教筛,莫比乌斯反演]

    \[\sum_{i=1}^{n}\sum_{j=1}^{n} ij\gcd(i,j)\] \[=\sum_{d=1}^{n} d \sum_{i=1}^{n}\sum_{j=1}^{n} ij[\gc ...

  3. [luogu3768] 简单的数学题 [杜教筛]

    题面: 传送门 实际上就是求: 思路: 看到gcd就先反演一下,过程大概是这样: 明显的一步反演 这里设,S(x)等于1到x的和 然后把枚举d再枚举T变成先枚举T再枚举其约数d,变形: 后面其中两项展 ...

  4. 【luogu3768】简单的数学题 欧拉函数(欧拉反演)+杜教筛

    题目描述 给出 $n$ 和 $p$ ,求 $(\sum\limits_{i=1}^n\sum\limits_{j=1}^nij\gcd(i,j))\mod p$ . $n\le 10^{10}$ . ...

  5. 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记

    最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...

  6. 【51NOD 1847】奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数)

    [51NOD 1847]奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数) 题面 51NOD \[\sum_{i=1}^n\sum_{j=1}^nsgcd(i,j)^k\] 其中\( ...

  7. 【刷题】洛谷 P3768 简单的数学题

    题目描述 由于出题人懒得写背景了,题目还是简单一点好. 输入一个整数n和一个整数p,你需要求出(\(\sum_{i=1}^n\sum_{j=1}^n ijgcd(i,j))~mod~p\),其中gcd ...

  8. 洛谷 P3768 简单的数学题

    https://www.luogu.org/problemnew/show/P3768 化简一下式子,就是$\sum_{d=1}^ncalc(d)d^2\varphi(d)$ 其中$calc(d)=\ ...

  9. LOJ# 572. 「LibreOJ Round #11」Misaka Network 与求和(min25筛,杜教筛,莫比乌斯反演)

    题意 求 \[ \sum_{i = 1}^{n} \sum_{i = 1}^{n} f(\gcd(i, j))^k \pmod {2^{32}} \] 其中 \(f(x)\) 为 \(x\) 的次大质 ...

随机推荐

  1. [转]RabbitMQ三种Exchange模式(fanout,direct,topic)的性能比较

    RabbitMQ中,所有生产者提交的消息都由Exchange来接受,然后Exchange按照特定的策略转发到Queue进行存储 RabbitMQ提供了四种Exchange:fanout,direct, ...

  2. 如何通过outline为SQL语句指定执行计划

    创建测试表 以用户jyu连接,创建测试表 SQL> conn jyu/jyu; Connected. SQL> create table t (id number, name varcha ...

  3. springmvc+spring3+hibernate4框架简单整合,简单实现增删改查功能

    转自:https://blog.csdn.net/thinkingcao/article/details/52472252 C 所用到的jar包     数据库表 数据库表就不用教大家了,一张表,很简 ...

  4. DAY10-MYSQL表操作

    一 存储引擎介绍 存储引擎即表类型,mysql根据不同的表类型会有不同的处理机制 http://www.cnblogs.com/guoyunlong666/p/8491702.html 二 表介绍 表 ...

  5. php5.6,curl上传的变化

    $ch = curl_init ();curl_setopt ( $ch, CURLOPT_SAFE_UPLOAD, false); //php5.6要加上这个 $fields = array(); ...

  6. css知多少(5)——选择器(转)

    css知多少(5)——选择器   1. 引言 从本节开始,就进入本系列的第二个部分——css和html的结合——说白了就是选择器. CSS中定义了样式,如何将这些样式设置到相应的html节点上?就不得 ...

  7. 使用HttpClient进行Get通信

    --------------siwuxie095                             首先到 Apache官网 下载相关的库文件     Apache官网:http://www.a ...

  8. go 语言介绍

    特点1. 静态类型,编译开源语言 2. 脚本化的语法,支持多种编程范式(函数式,面向对象) 3. 原生,给力的并发支持并发编程 Go语言的优势: 1.脚本化的语法:开发效率高,容易上手 2.静态类型+ ...

  9. ZROI2018普转提day1t1

    传送门 分析 我们先二分一下最终的平均值mid,然后让序列中的每一个数都减去这个mid,之后用新序列的前缀和建一棵线段树,枚举起点i,然后求出此时在i+L-1~i+R-1范围内的前缀和的最大值,用这个 ...

  10. 2015年阿里实习生面试Java研发工程师 小记

    5月5日,广州,阿里实习生面试,Java研发工程师,完全被虐orz 几乎没有Java项目开发经验,接近零基础,去水了一发,毫无悬念的被刷了..RP也是杠杠的,准备过的题目一个都没被问到,算法题也是一条 ...