# 【BZOJ4407】于神之怒加强版（莫比乌斯反演）

### 前言

$Jan\ 28th$刷题计划（3/6），算法标签：莫比乌斯反演&杜教筛。

### 莫比乌斯反演

$\sum_{d=1}^{min(n,m)}d^k\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac md\rfloor}[gcd(i,j)==1]$

$\sum_{d=1}^{min(n,m)}d^k\sum_{p=1}^{min(\lfloor\frac nd\rfloor,\lfloor\frac md\rfloor)}\mu(p)\lfloor\frac n{dp}\rfloor\lfloor\frac m{dp}\rfloor$

$\sum_{D=1}^{min(n,m)}\lfloor\frac nD\rfloor\lfloor\frac mD\rfloor\sum_{d|D}d^k\mu(\frac Dd)$

$f(D)=\sum_{d|D}d^k\mu(\frac Dd)$，则原式等同于：

$\sum_{D=1}^{min(n,m)}\lfloor\frac nD\rfloor\lfloor\frac mD\rfloor f(D)$

### 线性筛筛积性函数

$f(n)=\prod_{i=1}^tf(P_i^{a_i})$

$f(P_i^{a_i})=\sum_{d|P_i^{a_i}}d^k\mu(\frac Dd)=1^k\times\mu(P_i^{a_i})+P_i^k\times\mu(P_i^{a_i-1})+...+P_i^{a_i\times k}\times\mu(1)$

$f(P_i^{a_i})=P_i^{(a_i-1)\times k}\times\mu(P_i)+P_i^{a_i\times k}\times\mu(1)=-P_i^{(a_i-1)\times k}+P_i^{a_i\times k}=P_i^{(a_i-1)\times k}(P_i^k-1)$

$f(n)=\prod_{i=1}^tP_i^{(a_i-1)\times k}(P_i^k-1)$

$f(n)=\begin{cases}1&(n=1)\\p^k-1&(n\ is\ prime)\end{cases}$

$f(i\times P_j)=\begin{cases}f(i)\times f(P_j)&(P_j\not{|}i)\\f(i)\times P_i^k&(P_j|i)\end{cases}$

### 代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 10000000
#define X 1000000007
using namespace std;
int n,m,k;
I int Qpow(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
template<int SZ> class LinearSieve//线性筛
{
private:
int Pt,P[SZ+5],f[SZ+5],p[SZ+5];
public:
I int operator [] (CI x) Con {return f[x];}
I void Init()
{
RI i,j;for(f[1]=1,i=2;i<=SZ;++i)
{
!P[i]&&(P[++Pt]=i,p[i]=Qpow(i,k),f[i]=p[i]-1);
for(j=1;j<=Pt&&i*P[j]<=SZ;++j)
if(P[i*P[j]]=1,i%P[j]) f[i*P[j]]=1LL*f[i]*f[P[j]]%X;
else {f[i*P[j]]=1LL*f[i]*p[P[j]]%X;break;}
}
for(i=2;i<=SZ;++i) f[i]=(f[i]+f[i-1])%X;
}
};LinearSieve<N> F;
int main()
{
RI Tt,i,j,l,r,t;scanf("%d%d",&Tt,&k),F.Init();W(Tt--)
{
for(scanf("%d%d",&n,&m),t=0,l=1;l<=min(n,m);l=r+1)//除法分块
r=min(n/(n/l),m/(m/l)),t=(1LL*(n/l)*(m/l)%X*(F[r]-F[l-1]+X)+t)%X;
printf("%d\n",t);
}return 0;
}

posted @ 2020-01-28 16:14  TheLostWeak  阅读(...)  评论(...编辑  收藏