P3768 简单的数学题 杜教筛+推式子
\(\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
开始推式子
题目要求
\]
老规矩,枚举gcd
\]
把d提出来
\]
后面把d弄出来
\]
利用\(\mu * i = e\)套进去
\]
即
\]
改为枚举倍数
\]
看到这个式子,大为欣喜,于是
\]
\]
\]
于是以为这题切掉了?????
我TM。。数据范围尼玛\(10^9\)
\(how\ \ \ to \ \ \ O(\sqrt n ^2)\)
显然要继续往下推
某巨佬有一手,pd换q的操作(原式为kd换q)
于是,先将原式变为
\]
考虑枚举q,那么里面的kd就可以提出来了
\]
这里面的d有点突兀qwq
\]
上面的式子是有问题的,因为枚举的\(q=kd\),那么k应该是q的因子,所以要改一下枚举,同时后面的可以写成平方形式
\]
然后可以把q提出来
\]
然后因为有
\]
因此代回去
\]
卧槽,继续
\]
我Fuck, \(O(\sqrt n)\) 我就不信还过不了??
\]
\]
杜教筛+数列分块就行了
注意各种取模,少一个都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 简单的数学题 杜教筛+推式子的更多相关文章
- luogu P3768 简单的数学题 杜教筛 + 欧拉反演 + 逆元
求 $\sum_{i=1}^{n}\sum_{j=1}^{n}ijgcd(i,j)$ 考虑欧拉反演: $\sum_{d|n}\varphi(d)=n$ $\Rightarrow \sum_{i ...
- 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 ...
- [luogu3768] 简单的数学题 [杜教筛]
题面: 传送门 实际上就是求: 思路: 看到gcd就先反演一下,过程大概是这样: 明显的一步反演 这里设,S(x)等于1到x的和 然后把枚举d再枚举T变成先枚举T再枚举其约数d,变形: 后面其中两项展 ...
- 【luogu3768】简单的数学题 欧拉函数(欧拉反演)+杜教筛
题目描述 给出 $n$ 和 $p$ ,求 $(\sum\limits_{i=1}^n\sum\limits_{j=1}^nij\gcd(i,j))\mod p$ . $n\le 10^{10}$ . ...
- 莫比乌斯反演/线性筛/积性函数/杜教筛/min25筛 学习笔记
最近重新系统地学了下这几个知识点,以前没发现他们的联系,这次总结一下. 莫比乌斯反演入门:https://blog.csdn.net/litble/article/details/72804050 线 ...
- 【51NOD 1847】奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数)
[51NOD 1847]奇怪的数学题(莫比乌斯反演,杜教筛,min_25筛,第二类斯特林数) 题面 51NOD \[\sum_{i=1}^n\sum_{j=1}^nsgcd(i,j)^k\] 其中\( ...
- 【刷题】洛谷 P3768 简单的数学题
题目描述 由于出题人懒得写背景了,题目还是简单一点好. 输入一个整数n和一个整数p,你需要求出(\(\sum_{i=1}^n\sum_{j=1}^n ijgcd(i,j))~mod~p\),其中gcd ...
- 洛谷 P3768 简单的数学题
https://www.luogu.org/problemnew/show/P3768 化简一下式子,就是$\sum_{d=1}^ncalc(d)d^2\varphi(d)$ 其中$calc(d)=\ ...
- 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\) 的次大质 ...
随机推荐
- Python使用SMTP模块、email模块发送邮件
一.smtplib模块: 主要通过SMTP类与邮件系统进行交互.使用方法如下: 1.实例化一个SMTP对象: s = smtplib.SMTP(邮件服务地址,端口号) s = smtplib.SMTP ...
- iOS下拉图片放大
效果图 开始简单的代码过程 其实思路很简单 就是 让tableView偏移 一图片的高度,然后在把图片添加到tableView中,然后再监听didScrollView,在里面改变图片的frame - ...
- javascript 中的JSON.stringify - 将对象和数组转换为json格式(来源于网络)
JSON.stringify 函数 (JavaScript) 将 JavaScript 值转换为 JavaScript 对象表示法 (Json) 字符串. JSON.stringi ...
- 怎样增加phpmyadmin导入文件上限
1 2 3 分步阅读 百度经验:jingyan.baidu.com phpMyAdmin 是一个用PHP编写的,可以通过 web 方式控制和操作 MySQL 数据库.因为操作简单被广大的使用mysql ...
- Python 面向对象 (进阶篇)
<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可 ...
- 正则表达式计算 origin = "1 - 2 * ( ( 60 - 30 + ( -40.0 / 5 ) * ( 9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14 )) - ( - 4 * 3 ) / ( 16 - 3 * 2))"
#!/usr/bin/env python import re def f1(arg): return 1 origin = "1 - 2 * ( ( 60 - 30 + ( -40.0 / ...
- CSS布局奇淫巧计之-强大的负边距
css中的负边距(negative margin)是布局中的一个常用技巧,只要运用得合理常常会有意想不到的效果.很多特殊的css布局方法都依赖于负边距,所以掌握它的用法对于前端的同学来说,那是必须的. ...
- C++面向对象类的实例题目十
题目描述: 编写一个程序,其中有一个汽车类vehicle,它具有一个需要传递参数的构造函数,类中的数据成员:车轮个数wheels和车重weight放在保护段中:小车类car是它的私有派生类,其中包含载 ...
- SpringMVC_05 利用spring框架来处理异常
待更新... 2017年5月13日22:46:52 1 用spring框架来处理异常 将异常抛给spring框架,让spring框架来处理 异常:这样就不需要程序员去捕获异常啦 2 方法一:配置简单异 ...
- 使用批处理替换windows系统中的hosts文件
chcp 936 >nul@echo offmode con lines=30 cols=60%1 mshta vbscript:CreateObject("Shell.Applica ...