LG3768 简单的数学题
P3768 简单的数学题
题目描述
输入一个整数n和一个整数p,你需要求出$(\sum_{i=1}^n\sum_{j=1}^n ijgcd(i,j))~mod~p$,其中gcd(a,b)表示a与b的最大公约数。
输入输出格式
输入格式:
一行两个整数p、n。
输出格式:
一行一个整数$(\sum_{i=1}^n\sum_{j=1}^n ijgcd(i,j))~mod~p$。
输入输出样例
说明
对于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为质数。
题解
先推一波式子。
=\sum_{i=1}^n\sum_{j=1}^nij \sum_{d|i\wedge d|j}\varphi(d)\\
=\sum_{d=1}^n\varphi(d)\sum_{d|i}\sum_{d|j}ij\\
=\sum_{d=1}^n\varphi(d)d^2(\sum_{i=1}^{\lfloor\frac nd\rfloor}i)^2\\
=\sum_{d=1}^n\varphi(d)d^2S(\lfloor\frac nd\rfloor,3)
\]
其中\(S\)表示自然数幂和。所以只要能求出\(f(n)=\varphi(n)n^2\)的前缀和\(F(n)=\sum_{i=1}^nf(i)\),这个式子就能整数分块做。
考虑\(f(n)=\varphi(n)n^2\)它的形式,\(f=\varphi\cdot id^2\),符合杜教筛处理的形式。于是构造\(g(n)=n^2\),则
\]
而\(g,f*g\)的前缀和就是\(S(n,2),S(n,3)\),所以这个问题就解决了。最后列一下求和式:
=\sum_{i=1}^ni^3-\sum_{i=2}^ni^2F(\lfloor \frac ni\rfloor)
\]
时间复杂度\(O(n^\frac 23+n^\frac 12)\)。话说这题数据真的水,我减号写成加号都有60分。
#include<bits/stdc++.h>
#define il inline
#define co const
template<class T>T read(){
T data=0,w=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(T&x) {return x=read<T>();}
typedef long long LL;
using namespace std;
co int N=4641589;
int mod,i6;
int pri[N],tot,phi[N];
int add(int a,int b){
return (a+=b)>=mod?a-mod:a;
}
int mul(int a,int b){
return (LL)a*b%mod;
}
int fpow(int a,int b){
int ans=1;
for(;b;b>>=1,a=mul(a,a))
if(b&1) ans=mul(ans,a);
return ans;
}
void init(){
i6=fpow(6,mod-2);
pri[1]=phi[1]=1;
for(int i=2;i<N;++i){
if(!pri[i]) pri[++tot]=i,phi[i]=i-1;
for(int j=1;j<=tot&&i*pri[j]<N;++j){
pri[i*pri[j]]=1,phi[i*pri[j]]=phi[i]*phi[pri[j]];
if(i%pri[j]==0){
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
}
}
for(int i=2;i<N;++i) phi[i]=add(phi[i-1],mul(phi[i],mul(i,i)));
}
int sum_s2(int n){
return mul(i6,mul(n,mul(n+1,2*n+1)));
}
int sum_s3(int n){
return n&1?mul(mul(n,(n+1)/2),mul(n,(n+1)/2)):mul(mul(n/2,n+1),mul(n/2,n+1));
}
map<LL,int> sf;
int sum_f(LL n){
if(n<N) return phi[n];
if(sf.count(n)) return sf[n];
int ans=sum_s3(n%mod);
for(LL l=2,r;l<=n;l=r+1){
r=n/(n/l);
ans=add(ans,mod-mul(add(sum_s2(r%mod),mod-sum_s2((l-1)%mod)),sum_f(n/l)));
}
return sf[n]=ans;
}
int solve(LL n){
int ans=0;
for(LL l=1,r;l<=n;l=r+1){
r=n/(n/l);
ans=add(ans,mul(add(sum_f(r),mod-sum_f(l-1)),sum_s3(n/l%mod)));
}
return ans;
}
int main(){
cerr<<(sizeof(pri)+sizeof(phi))/1024.0/1024<<endl;
read(mod);
init();
printf("%d\n",solve(read<LL>()));
return 0;
}
LG3768 简单的数学题的更多相关文章
- 【LG3768】简单的数学题
[LG3768]简单的数学题 题面 求 \[ (\sum_{i=1}^n\sum_{j=1}^nij\text{gcd}(i,j))\text{mod}p \] 其中\(n\leq 10^{10},5 ...
- 【数学】HPU--1037 一个简单的数学题
1037: 一个简单的数学题 [数学] 时间限制: 1 Sec 内存限制: 128 MB提交: 259 解决: 41 统计 题目描述 小明想要知道$a^b$的值,但是这个值会非常的大. 所以退而求其次 ...
- 【Luogu3768】简单的数学题(莫比乌斯反演,杜教筛)
[Luogu3768]简单的数学题(莫比乌斯反演,杜教筛) 题面 洛谷 \[求\sum_{i=1}^n\sum_{j=1}^nijgcd(i,j)\] $ n<=10^9$ 题解 很明显的把\( ...
- luoguP3768 简单的数学题
题目链接 luoguP3768 简单的数学题 题解 上面那个式子的最后一步,需要定理 用数学归纳法证明 \(S1=1^3=1^2\) \(S2=1^3+2^3=9=3^2=(1+2)^2\) \(S3 ...
- 洛谷 P3768 简单的数学题 解题报告
P3768 简单的数学题 题目描述 由于出题人懒得写背景了,题目还是简单一点好. 输入一个整数\(n\)和一个整数\(p,\)你需要求出\((\sum_{i=1}^n\sum_{j=1}^n ijgc ...
- loj#6229 这是一道简单的数学题
\(\color{#0066ff}{ 题目描述 }\) 这是一道非常简单的数学题. 最近 LzyRapxLzyRapx 正在看 mathematics for computer science 这本书 ...
- 「洛谷P3768」简单的数学题 莫比乌斯反演+杜教筛
题目链接 简单的数学题 题目描述 输入一个整数n和一个整数p,你需要求出 \[\sum_{i=1}^n\sum_{j=1}^n (i\cdot j\cdot gcd(i,j))\ mod\ p\] ...
- P3768 【简单的数学题】
P3768 [简单的数学题] \(Ans=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ijgcd(i,j)\) \(=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ij\ ...
- NYOJ 330 一个简单的数学题【数学题】
/* 题目大意:求解1/n; 解题思路:写一个输出小数的算法 关键点:怎样处理小数点循环输出 解题人:lingnichong 解题时间:2014-10-18 09:04:22 解题体会:输出小数的算法 ...
随机推荐
- Postman系列三:Postman中post接口实战(上传文件、json请求)
一:接口测试过程中GET请求与POST请求的主要区别 从开发角度我们看get与post的主要区别是:1.Get是用来从服务器上获得数据,而Post是用来向服务器上传递数据:2.Get安全性比Post低 ...
- SQL中EXPLAIN命令详解---(转)
MySQL Explain详解 在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQ ...
- 关于su下bash:xxx :command not found
今天在新建组的时候出了问题: $ su Password: # groupadd prj bash: groupadd :command not found 我就纳闷,明明是在su权限下,怎么还不能使 ...
- (七)linux 学习 -- 键盘高级操作技巧
The Linux Command Line 读书笔记 - 部分内容来自 http://billie66.github.io/TLCL/book/chap09.html 文章目录 移动光标 修改文本 ...
- Django项目常见面试问题
1.python中的lambda是什么意思,可以举例 匿名函数 a = lambda x:x+1 print(a(1)) 2.请写出以下代码执行的结果 class Parent(object): x ...
- git简单介绍
一种常见的版本控制工具 获取 克隆仓库 git支持以ssh或者http的方式来标识远程仓库 git clone git@github.com:username/project.git git clon ...
- vue 仿写微信公众号自定义菜单
先看效果图 代码参考 <template> <div> <!-- 公众号设置 --> <el-col :span="24" style=& ...
- 5_PHP数组_3_数组处理函数及其应用_9_数组集合运算函数
以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. 数组集合运算函数 1. array_merge() 函数 程序: <?php $array1 = array ...
- gitlab异地备份并验证MD5值
最近公司发生了蛮多事情的,唉,咱也不管问啊,好好干活吧 需求 把gitlab的备份文件异地备份一份,备份无论失败还是成功通知某邮箱 实现思路 先rsync文件过去,判断rsync这个步骤有没有成功,失 ...
- iOS数组遍历
对于一个数组 NSArray *array = @[@"111",@"222",@"333",@"444",@" ...