题目背景

Salamander的家门口是一条长长的公路。

又是一年春天将至,Salamander发现路边长出了一排毒瘤!

Salamander想带一些毒瘤回家,但是,这时毒瘤当中钻出来了一个毒瘤之神!

毒瘤之神:你想要带毒瘤走吗?想要带走毒瘤,就必须回答我的问题!如果答不出来的话,你还是乖乖回家吧!

题目描述

毒瘤之神会问T次,每次给定n,m,Salamander需要回答出\(\sum_{i=1}^n\sum_{j=1}^m\varphi(ij)\ mod\ 998244353\)。

Salamander这么辣鸡当然不会做啦,于是把问题丢给了你。

输入输出格式

输入格式:

第一行包含一个正整数T。

接下来T行,每行包含两个正整数,用空格隔开,表示这次询问的n,m。

输出格式:

包含T行每行一个整数表示答案。

输入输出样例

输入样例#1:

3
1 1
2 2
3 3

输出样例#1:

1
5
19

Solution

神奇的反演题。。

首先有一个比较显然的性质:

\[\varphi(ij)=\frac{\varphi(i)\varphi(j)\gcd(i,j)}{\varphi(\gcd(i,j))}
\]

证明对于每个质因子考虑就行了。

然后带进去莫比乌斯反演:

\[\begin{align}
ans=&\sum_{i=1}^{n}\sum_{j=1}^m\frac{\varphi(i)\varphi(j)\gcd(i,j)}{\varphi(\gcd(i,j))}\\
=&\sum_{T=1}^{\min(n,m)}\sum_{d|T}\frac{d}{\varphi(d)}\cdot \mu(\frac{T}{d}) \sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\varphi(iT)\sum_{j=1}^{\lfloor\frac{m}{T}\rfloor}\varphi(jT)
\end{align}
\]

设:

\[f(n)=\sum_{d|n}\frac{d}{\varphi(d)}\cdot \mu(\frac{n}{d})
\]

显然这玩意可以\(O(n\log n)\)预处理出来。

对于后面那个,设:

\[g(n,T)=\sum_{i=1}^{n}\varphi(iT)
\]

然后因为\(n\cdot T\leqslant 1e5\),所以总共只有\(O(n\log n)\)个值,动态开内存预处理出来就行。

答案变成了:

\[ans=\sum_{t=1}^{\min(n,m)}f(t)g(\lfloor\frac{n}{t}\rfloor,t)g(\lfloor\frac{m}{t}\rfloor,t)
\]

答案是一个数论分块的形式,设:

\[h(n,m,t)=\sum_{i=1}^{t}f(i)g(n,i)g(m,i)
\]

然后我们预处理出\(n,m\leqslant B\)的值,这里先设一个\(B\)出来,现在并不知道他是多少。

然后分析下复杂度,此时\(ans\)里的\(T\geqslant n/B\),所以对于\(T \leqslant n/B\)的直接暴力来算出就好了,剩下的数论分块之后利用\(h\)减一下就好了。

时间复杂度为\(O(n\log n+B^2n+T(\sqrt{n}+\lfloor\frac{n}{B}\rfloor))\)。

取最小值即\(B^2n=T\cdot \frac{n}{B}\),解得\(B=\sqrt[3]{T}\thickapprox 30\)。

#include<bits/stdc++.h>
using namespace std; void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
} void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');} #define pb push_back const int maxn = 1e5+10;
const int B = 30;
const int mod = 998244353; int pri[maxn],mu[maxn],vis[maxn],tot,f[maxn],phi[maxn],inv[maxn];
vector <int > g[maxn],h[B+1][B+1]; void prepare(int n) {
mu[1]=inv[1]=phi[1]=1;
for(int i=2;i<=n;i++) {
if(!vis[i]) mu[i]=-1,pri[++tot]=i,phi[i]=i-1;
for(int j=1;j<=tot&&i*pri[j]<=n;j++) {
vis[i*pri[j]]=1;
if(i%pri[j]==0) {phi[i*pri[j]]=phi[i]*pri[j];break;}
mu[i*pri[j]]=-mu[i];
phi[i*pri[j]]=phi[i]*(pri[j]-1);
}
inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
} for(int d=1;d<=n;d++)
for(int T=d;T<=n;T+=d)
f[T]=(f[T]+1ll*d*inv[phi[d]]%mod*mu[T/d])%mod; for(int i=0;i<=n;i++) g[0].pb(0);
for(int i=1;i<=n;i++) {
int l=(n/i);g[i].pb(0);
for(int j=1;j<=l;j++)
g[i].pb((g[i-1][j]+phi[i*j])%mod);
} for(int i=1;i<=B;i++)
for(int j=1;j<=B;j++) {
int l=min(n/i,n/j);h[i][j].pb(0);
for(int k=1;k<=l;k++)
h[i][j].pb((h[i][j][k-1]+1ll*f[k]*g[i][k]%mod*g[j][k]%mod)%mod);
} } void solve() {
int n,m;read(n),read(m);if(n>m) swap(n,m);
int ans=0;
for(int i=1;i<=m/B;i++) ans=(ans+1ll*f[i]*g[n/i][i]%mod*g[m/i][i]%mod)%mod;
int T=m/B+1;
while(T<=n) {
int pre=T;T=min(n/(n/T),m/(m/T));
ans=(1ll*(ans+h[n/T][m/T][T])-h[n/T][m/T][pre-1])%mod;T++;
}write((ans+mod)%mod);
} int main() {
prepare(100000);
int t;read(t);
while(t--) solve();
return 0;
}

[luogu 4240] 毒瘤之神的考验的更多相关文章

  1. luogu 4240 毒瘤之神的考验 (莫比乌斯反演)

    题目大意:略 题面传送门 果然是一道神duliu题= = 出题人的题解传送门 出题人的题解还是讲得很明白的 1.关于$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m ...

  2. 洛谷 P4240 毒瘤之神的考验 解题报告

    P4240 毒瘤之神的考验 题目背景 \(\tt{Salamander}\)的家门口是一条长长的公路. 又是一年春天将至,\(\tt{Salamander}\)发现路边长出了一排毒瘤! \(\tt{S ...

  3. P4240 毒瘤之神的考验

    题目 P4240 毒瘤之神的考验 神仙题\(emmm\) 前置 首先有一个很神奇的性质: \(\varphi(ij)=\dfrac{\varphi(i)\varphi(j)gcd(i,j)}{\var ...

  4. 洛谷 P4240 - 毒瘤之神的考验(数论+复杂度平衡)

    洛谷题面传送门 先扯些别的. 2021 年 7 月的某一天,我和 ycx 对话: tzc:你做过哪些名字里带"毒瘤"的题目,我做过一道名副其实的毒瘤题就叫毒瘤,是个虚树+dp yc ...

  5. Luogu 4240:毒瘤之神的考验

    传送门 Sol 分开考虑 \(\varphi(ij)\) 中 \(ij\) 的质因子 那么 \[\varphi(ij)=\frac{\varphi(i)\varphi(j)gcd(i,j)}{\var ...

  6. 从 [P4240 毒瘤之神的考验] 谈 OI 中的美学

    感觉这题真的特别有意思,涉及了 OI 中很多非常有意思.非常美的手法,比如--平衡两部分的时间复杂度.\(n \ln n\) 的那个 Trick等等,真的一种暴力的美学. 题目大意: 多组询问,求 \ ...

  7. 洛谷P4240 毒瘤之神的考验 【莫比乌斯反演 + 分块打表】

    题目链接 洛谷P4240 题解 式子不难推,分块打表真的没想到 首先考虑如何拆开\(\varphi(ij)\) 考虑公式 \[\varphi(ij) = ij\prod\limits_{p | ij} ...

  8. luogu4240 毒瘤之神的考验(毒瘤乌斯反演)

    link 题意:求出\(\sum_{i=1}^n\sum_{j=1}^m\varphi(ij)\),对998244353取模 多组数据,\(T\le 10^4,n,m\le 10^5\). 前置知识: ...

  9. Luogu4240 毒瘤之神的考验 莫比乌斯反演、根号分治

    传送门 首先有\(\varphi(ij) = \frac{\varphi(i) \varphi(j) \gcd(i,j)}{\varphi(\gcd(i,j))}\),把欧拉函数的定义式代入即可证明 ...

随机推荐

  1. 08_1_IO

    08_1_IO 1. 输入/输出流的分类 java.io包中定义了多个流类型(类或抽象类)来实现输入/输出功能:可以从不同的角度对其进行分类: 按数据流的方向不同可以分给输入流和输出流. 按处理数据单 ...

  2. java基础1.5版后新特性 自动装箱拆箱 Date SimpleDateFormat Calendar.getInstance()获得一个日历对象 抽象不要生成对象 get set add System.arrayCopy()用于集合等的扩容

    8种基本数据类型的8种包装类 byte Byte short Short int Integer long Long float Float double Double char Character ...

  3. CSU1216: 异或最大值(01Trie树)

    Description 给定一些数,求这些数中两个数的异或值最大的那个值 Input 多组数据.第一行为数字个数n,1 <= n <= 10 ^ 5.接下来n行每行一个32位有符号非负整数 ...

  4. dicom和dicomdir

    转载http://blog.sina.com.cn/s/blog_4bce5f4b01019ix5.html DICOM 文件内容在 Part 3 DICOM IOD 里定义.CT, MR, CR, ...

  5. PLC状态机编程第三篇-RS信号处理

    我们今天简要介绍RS指令在状态机中怎么处理的.有些设备按下停止按钮后,没有马上停止,而是到原点后才停止,那么这种情况在状态机中如何表示呢?我们以案例说明之,下面是我们的控制描述. 控制描述 小车从左位 ...

  6. C语言字符篇(四)字符串查找函数

      #include <string.h>   char *strchr(const char *s, int c);   The strchr() function returns a ...

  7. C语言数组篇(一)一维数组

       0.  数组的两种表现形式         一种是常见的a[10];         //初学者常用         另一种是用指针表示的数组.   //实际工程使用.常用于参数传递       ...

  8. python搭建友盟以及个推推送web服务器

    一.友盟客户端demo: 由于SDK原因,新版Android Studio的Android API 28 Platform无法同步新建项目, 所以我最终选择下载android-studio-bundl ...

  9. JAVA运行机制

    这一篇我们来简单理解一下JAVA的运行机制 大概可以分为三大部分 1.编写程序 2.编译程序 3.运行程序 1.编写程序 编写程序就是我们前面说的源代码 这些源代码都有特殊的语法 例如main函数 他 ...

  10. Sqoop 工具使用

    Sqoop 是什么及安装 Hadoop sqoop Apache sqoop (SQL to Hadoop) Sqoop is a tool designed to transfer data bet ...