P4240 毒瘤之神的考验 题解
目录
题目描述
组询问,给定 ,求 。
数据范围
- 。
时间限制 ,空间限制 。
分析
首先有一个经典结论:
证明:
若 ,则 在两边的贡献均为 。
若 ,则 在左边的贡献为 ,右边的贡献为 。
其实证明很 ,真正有用的是把这个式子积累下来,如果忘了也可以通过比较 和 的差距现推。
接下来是常规操作。
令 ,则 可以 预处理, 的状态数为调和级数,同样可以 预处理。
原式化为:
虽然看到了 ,但是不能整除分块。这是因为 内部仍然和 有关。
记 ,考虑根号分治:
- 如果 ,暴力枚举 即可,时间复杂度 。
- 如果 ,则 。对 ,预处理 ,整除分块可以做到 回答。
由于 要求 ,因此 的状态数为 ,可以接受。
时间复杂度 ,取 ,时空复杂度均为 。
#include<bits/stdc++.h>
using namespace std;
const int B=200,maxn=1e5+5,mod=998244353;
int m,n,t,res;
int p[maxn],mu[maxn],phi[maxn];
int f[maxn];
vector<int> g[maxn],s[B+5][B+5];
bitset<maxn> b;
int qpow(int a,int k)
{
int res=1;
for(;k;a=1ll*a*a%mod,k>>=1) if(k&1) res=1ll*res*a%mod;
return res;
}
void init(int n)
{
mu[1]=phi[1]=1;
for(int i=2,cnt=0;i<=n;i++)
{
if(!b[i]) p[++cnt]=i,mu[i]=-1,phi[i]=i-1;
for(int j=1;j<=cnt&&i*p[j]<=n;j++)
{
b[i*p[j]]=1;
if(i%p[j]==0)
{
phi[i*p[j]]=phi[i]*p[j];
break;
}
mu[i*p[j]]=-mu[i],phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
for(int i=1;i<=n;i++)
{
g[i].resize(n/i+5);
for(int j=1,inv=qpow(phi[i],mod-2);i*j<=n;j++)
{
f[i*j]=(f[i*j]+1ll*i*inv*mu[j])%mod;
g[i][j]=(g[i][j-1]+phi[i*j])%mod;
}
}
for(int i=1;i<=B;i++)
for(int j=1;j<=i;j++)
{
s[i][j].resize(n/i+5);
for(int k=1;k<=n/i;k++)
s[i][j][k]=(s[i][j][k-1]+1ll*f[k]*g[k][i]%mod*g[k][j])%mod;
}
}
int main()
{
scanf("%d",&t),init(maxn-5);
while(t--)
{
scanf("%d%d",&n,&m),res=0;
if(n<m) swap(n,m);
for(int i=1;i<=min(n/B,m);i++) res=(res+1ll*f[i]*g[i][n/i]%mod*g[i][m/i])%mod;
for(int l=n/B+1,r=0;l<=m;l=r+1)
{
r=min(n/(n/l),m/(m/l));
res=(0ll+res+s[n/l][m/l][r]-s[n/l][m/l][l-1])%mod;
}
printf("%lld\n",(res+mod)%mod);
}
return 0;
}
本文来自博客园,作者:peiwenjun,转载请注明原文链接:https://www.cnblogs.com/peiwenjun/p/18570764
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】