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$。

输入输出样例

输入样例#1:
复制

998244353 2000
输出样例#1:
复制

883968974

说明

对于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\gcd(i,j)\\
=\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\),则

\[(f*g)(n)=\sum_{d|n}\varphi(d)d^2(\frac nd)^2=n^3
\]

而\(g,f*g\)的前缀和就是\(S(n,2),S(n,3)\),所以这个问题就解决了。最后列一下求和式:

\[F(n)=\sum_{i=1}^n(f*g)(i)-\sum_{i=2}^ng(i)F(\lfloor \frac ni\rfloor)\\
=\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 简单的数学题的更多相关文章

  1. 【LG3768】简单的数学题

    [LG3768]简单的数学题 题面 求 \[ (\sum_{i=1}^n\sum_{j=1}^nij\text{gcd}(i,j))\text{mod}p \] 其中\(n\leq 10^{10},5 ...

  2. 【数学】HPU--1037 一个简单的数学题

    1037: 一个简单的数学题 [数学] 时间限制: 1 Sec 内存限制: 128 MB提交: 259 解决: 41 统计 题目描述 小明想要知道$a^b$的值,但是这个值会非常的大. 所以退而求其次 ...

  3. 【Luogu3768】简单的数学题(莫比乌斯反演,杜教筛)

    [Luogu3768]简单的数学题(莫比乌斯反演,杜教筛) 题面 洛谷 \[求\sum_{i=1}^n\sum_{j=1}^nijgcd(i,j)\] $ n<=10^9$ 题解 很明显的把\( ...

  4. luoguP3768 简单的数学题

    题目链接 luoguP3768 简单的数学题 题解 上面那个式子的最后一步,需要定理 用数学归纳法证明 \(S1=1^3=1^2\) \(S2=1^3+2^3=9=3^2=(1+2)^2\) \(S3 ...

  5. 洛谷 P3768 简单的数学题 解题报告

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

  6. loj#6229 这是一道简单的数学题

    \(\color{#0066ff}{ 题目描述 }\) 这是一道非常简单的数学题. 最近 LzyRapxLzyRapx 正在看 mathematics for computer science 这本书 ...

  7. 「洛谷P3768」简单的数学题 莫比乌斯反演+杜教筛

    题目链接 简单的数学题 题目描述 输入一个整数n和一个整数p,你需要求出 \[\sum_{i=1}^n\sum_{j=1}^n (i\cdot j\cdot gcd(i,j))\ mod\ p\]  ...

  8. P3768 【简单的数学题】

    P3768 [简单的数学题] \(Ans=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ijgcd(i,j)\) \(=\sum ^{n}_{i=1}\sum ^{n}_{j=1}ij\ ...

  9. NYOJ 330 一个简单的数学题【数学题】

    /* 题目大意:求解1/n; 解题思路:写一个输出小数的算法 关键点:怎样处理小数点循环输出 解题人:lingnichong 解题时间:2014-10-18 09:04:22 解题体会:输出小数的算法 ...

随机推荐

  1. python文件夹操作

    1.遍历文件夹下所有文件2.将后缀为.DCM的文件复制到指定文件夹 import os import shutil def all_path(dirname): result = []#所有的文件 f ...

  2. Charles手机代理设置

      Charles工具 手机 方法/步骤     1.打开Charles   点击Proxy,选择proxy settings,输入端口8888   打开电脑,在cmd中输入ipconfig,查看本地 ...

  3. C语言单链表简单实现(简单程序复杂化)

    PS: goto还是很好玩的. #include <stdio.h> #include <stdlib.h> typedef struct _node{ int value; ...

  4. linux初识1

    linux 操作系统 概念性的理解 1.Linux内置解释器bash 相当于pyhon解释器 2.Linux的内部大多是使用python去书写 云计算 1.只需要 花钱,买腾讯,阿里云服务器 2.专人 ...

  5. kubernetes 实践三:使用kubeadm安装k8s1.16.0

    环境版本说明: 三台vmware虚拟机,系统版本CentOS7.6. Kubernetes 1.16.0,当前最新版. flannel v0.11 docker 18.09 使用kubeadm可以简单 ...

  6. Spring Cloud--服务的发布与调用示例

    [Provider] 引依赖: 启动类上添加注解: 配置文件: [Consumer] 引依赖: 加注解: 配置文件: 调用服务: 方式一(动态获取服务列表): Eureka默认30秒拉取一次服务列表. ...

  7. yii2 发送邮件 yii\swiftmailer\Mailer

    Yii2 中发送邮件 yii\swiftmailer\Mailer 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', 'viewPath ...

  8. ultraedit 实际应用技巧

    Tip 1: Alt+C 列模式可以说最初选择使用这个文本编辑软件,原因很简单,就是因为“她”具有列编辑模式.如果您还不知道什么是列编辑模式的话,我想您应该好好研究一下啦.这是一个超级“赞”的功能.在 ...

  9. Jupyter交互式工具安装使用

    Jupyter交互式工具安装使用 Jupyter Notebook(此前被称为IPython notebook)是一个交互式笔记本,支持运行 40 多种编程语言. 文档:https://jupyter ...

  10. Core 导出(流和URL两种)

    1.流 2.URL 两种都是使用Epplus 1. EPPlus的基本介绍 EPPlus是一个使用Open Office XML(xlsx)文件格式,能读写Excel 2007/2010 文件的开源组 ...