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 解题体会:输出小数的算法 ...
随机推荐
- js图表库
highcharts:https://www.hcharts.cn/ 商用收费,个人.公益免费,业界良心 百度家也有个echarts:http://echarts.baidu.com/ 免费,有许多小 ...
- 【LeetCode】删除排序数组中的重复项&&移除特定元素【双指针,原地算法】
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 1 ...
- 【LEETCODE】57、数组分类,适中级别,题目:969、442、695
package y2019.Algorithm.array.medium; import java.util.ArrayList; import java.util.List; /** * @Proj ...
- mysql常用处理时间的相关函数
1.DATE_ADD() 函数向日期添加指定的时间间隔 DAY) AS OrderPayDate FROM Orders 2.DATE_SUB() 函数从日期减去指定的时间间隔 DAY) AS Sub ...
- [CodeChef-ANUDTQ] Dynamic Trees and Queries
类似维护括号序列,给每个点建两个点,然后所有操作都能轻松支持了.注意sum和lastans是long long. #include<cstdio> #include<algorith ...
- python ID3决策树实现
环境:ubuntu 16.04 python 3.6 数据来源:UCI wine_data(比较经典的酒数据) 决策树要点: 1. 如何确定分裂点(CART ID3 C4.5算法有着对应的分裂计算方式 ...
- node.js开发 npm包管理工具 npm 和 cnpm区别
npm 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用. 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用 np ...
- 数据结构与算法(周测9-B树与B+树)
由于博主太菜,题目集还不完整,有待更新. 判断题 1.m阶B树的根结点最多有m棵子树. T F 2.In a B+ tree, leaves and nonleaf nodes h ...
- vue标签内循环数据逗号分隔
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- js 字节操作
获取byte的高4位bit和低4位bit function getHeight4(ata){//获取高四位 int height; height = ((data & 0xf0) >&g ...