【BZOJ4173】数学(欧拉函数)
- 求 \(\phi(n)\times\phi(m)\times \sum_{n\%k+m\%k\ge k}\phi(k)\)。
- \(n,m\le10^{15}\)
贡献转化+欧拉函数
考虑\(n\%k+m\%k\ge k\)充要于\(\lfloor\frac{n+m}k\rfloor=\lfloor\frac nk\rfloor+\lfloor\frac mk\rfloor+1\)。
因此我们实际上可以用\((\lfloor\frac{n+m}k\rfloor-\lfloor\frac nk\rfloor-\lfloor\frac mk\rfloor)\times\phi(k)\)来表示一个数\(k\)的贡献。
由此得出答案的计算式:
\[\phi(n)\times\phi(m)\times(\sum_{k=1}^{n+m}\phi(k)\times\lfloor\frac{n+m}k\rfloor-\sum_{i=1}^n\phi(k)\times\lfloor\frac nk\rfloor-\sum_{i=1}^m\phi(k)\times\lfloor\frac mk\rfloor)
\]
\(\sum_{k=1}^n\phi(k)\times\lfloor\frac nk\rfloor\) 其实是一个经典式子。根据\(\sum_{d|n}\phi(d)=n\),我们发现:
\[\sum_{i=1}^ni=\sum_{i=1}^n\sum_{k|i}\phi(k)=\sum_{k=1}^n\phi(k)\times\lfloor\frac nk\rfloor
\]
所以原式就等价于:
\[\phi(n)\times\phi(m)\times(\sum_{i=1}^{n+m}i-\sum_{i=1}^ni-\sum_{i=1}^mi)=\phi(n)\times\phi(m)\times nm
\]
代码:\(O(\sqrt n)\)
#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 LL long long
#define X 998244353
using namespace std;
LL n,m;I LL Phi(LL x)//求φ(x)
{
LL t=1;for(RI i=2;1LL*i*i<=x;++i) if(!(x%i)) {t*=i-1,x/=i;W(!(x%i)) t*=i,x/=i;}
return x^1&&(t*=x-1),t;
}
int main()
{
return scanf("%lld%lld",&n,&m),printf("%d\n",(Phi(n)%X)*(Phi(m)%X)%X*(n%X)%X*(m%X)%X),0;
}
待到再迷茫时回头望,所有脚印会发出光芒