luogu3768 简单的数学题
题意:∑ni=1∑nj=1ijgcd
对输入的某素数取模,一组询问,n\le10^{10},最大一组时限6s
推式子(orz某题解推了三行。。。)
\sum_{i=1}^n\sum_{j=1}^nij\gcd(i,j)
=\sum_{p=1}^np\sum_{i=1}^n\sum_{j=1}^nij[\gcd(i,j)=p]
=\sum_{p=1}^np^3\sum_{i=1}^{n/p}\sum_{j=1}^{n/p}ij[\gcd(i,j)=1]
=\sum_{p=1}^np^3\sum_{i=1}^{n/p}\sum_{j=1}^{n/p}ij\sum_{d|i,d|j}\mu(d)
=\sum_{p=1}^np^3\sum_{d=1}^n\mu(d)d^2\sum_{i=1}^{n/pd}\sum_{j=1}^{n/pd}ij
=\sum_{q=1}^nq^2(\sum_{d|q}\mu(d)\frac qd)(\sum_{i=1}^{n/q}i)^2
=\sum_{q=1}^nq^3(\sum_{d|q}\frac {\mu(d)}d)(\sum_{i=1}^{n/q}i)^2
=\sum_{q=1}^nq^3(\frac{\varphi(q)}q)(\sum_{i=1}^{n/q}i)^2
=\sum_{q=1}^nq^2\varphi(q)(\sum_{i=1}^{n/q}i)^2
整除分块+杜教筛(类似loj这是一道简单的数学题)
具体还是找个小样例跑一下就行了...
#include <cstdio>
using namespace std;
#define int long long
int n, p, prime[3000010], tot, phi[3000010], cjh = 3000000;
bool vis[3000010];
int qpow(int x, int y)
{
int res = 1;
while (y > 0)
{
if (y & 1) res = res * (long long)x % p;
x = x * (long long)x % p;
y >>= 1;
}
return res;
}
int inv2, inv6;
int s1(int x) { x %= p; return x * (long long)(x + 1) % p * inv2 % p; }
int s2(int x) { x %= p; return x * (long long)(x + 1) % p * (x * 2 + 1) % p * inv6 % p; }
int s3(int x) { return qpow(s1(x), 2); }
bool count[3000010];
int ans[3000010];
int chuans(int x)
{
if (x <= cjh) return phi[x];
if (count[n / x]) return ans[n / x];
count[n / x] = true;
int res = s3(x);
for (int i = 2, j; i <= x; i = j + 1)
j = (x / (x / i)), res = ((res - ((s2(j) - s2(i - 1)) * (long long)chuans(x / i) % p)) % p + p) % p;
return ans[n / x] = res;
}
signed main()
{
scanf("%lld%lld", &p, &n), phi[1] = 1;
inv2 = qpow(2, p - 2), inv6 = qpow(6, p - 2);
for (int i = 2; i <= cjh; i++)
{
if (vis[i] == false) prime[++tot] = i, phi[i] = i - 1;
for (int j = 1; j <= tot && i * prime[j] <= cjh; j++)
{
vis[i * prime[j]] = true;
if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; }
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
phi[i] = phi[i] * (long long)i % p * i % p;
phi[i] = (phi[i] + phi[i - 1]) % p;
}
int res = 0;
for (int i = 1, j; i <= n; i = j + 1)
j = (n / (n / i)), res = ((res + ((s3(n / i) - s3(n / (j + 1))) * (long long)chuans(j)) % p) % p + p) % p;
printf("%lld\n", res);
return 0;
}
不define int long long莫名WA了两个点。。
分类:
数学
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 历时 8 年,我冲上开源榜前 8 了!
· 物流快递公司核心技术能力-海量大数据处理技术
· 四大AI编程工具组合测评
· 关于能否用DeepSeek做危险的事情,DeepSeek本身给出了答案
· 如何在 Github 上获得 1000 star?