原题链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=4173
貌似题目是付费才可以看的。这里阐述一下题意吧:
定义整数集合 S(n,m)
它表示所有满足 n mod k+m mod k≥k 的所有的k组成的集合。
要求你计算
φ(n)φ(m)∑i∈S(n,m)φ(i) mod 998244353
<script type="math/tex; mode=display" id="MathJax-Element-56"></script>
题意有:
answerφ(n)φ(m)=∑i=1n+mφ(i)[n mod i+m mod i≥i]
n mod i+m mod i≥i
的对立条件:
n mod i+m mod i<i
也就是说:
n mod i+m mod i=(n+m)mod i
则:
n−⌊ni⌋i+m−⌊mi⌋i=(n+m)−⌊n+mi⌋i
那么也就是说:
⌊ni⌋+⌊mi⌋=⌊n+mi⌋
对于:
⌊n+mi⌋=⌊ni⌋+⌊mi⌋+⌊{ni}+{mi}⌋
0≤{ni}+{mi}<2
所以:
⌊n+mi⌋−⌊ni⌋−⌊mi⌋=0 or 1
则 n mod i+m mod i≥i 等价于:
⌊n+mi⌋−⌊ni⌋−⌊mi⌋=1
所以:
∑i=1n+mφ(i)[n mod i+m mod i≥i]=∑i=1n+mφ(i)(⌊n+mi⌋−⌊ni⌋−⌊mi⌋)=∑i=1n+mφ(i)⌊n+mi⌋−∑i=1nφ(i)⌊ni⌋−∑i=1mφ(i)⌊mi⌋
对于:
∑i=1nφ(i)⌊ni⌋=∑i=1nφ(i)∑i|d,d≤n1=∑d=1n∑i|dφ(i)=∑d=1nd=n(n+1)2
所以:
answer=φ(n)φ(m)((n+m)(n+m+1)−n(n+1)−m(m+1)2)
代码:
#include <algorithm>
#include <vector>
#include <stdio.h>
#include <cmath>
using namespace std;
typedef long long LL;
const LL P=998244353;
LL phi(LL n)
{
LL tmp=n;
for(LL k=2;k*k<=n;k++)
{
if(n%k)continue;
tmp=tmp-tmp/k;
while(n%k==0)n/=k;
}
if(n>1)tmp=tmp-tmp/n;
return tmp;
}
LL Pow(LL a,LL b)
{
LL tmp=1;
while(b)
{
if(b&1)
tmp=tmp*a%P;
a=a*a%P;
b>>=1;
}
return tmp;
}
int main ()
{
LL n,m;
scanf("%lld %lld",&n,&m);
LL ans=(phi(n)%P)*(phi(m)%P)%P;
n%=P;
m%=P;
LL Iv2=Pow(2,P-2);
ans=ans*(((n+m)*(n+m+1)%P*Iv2%P-n*(n+1)%P*Iv2%P-m*(m+1)%P*Iv2%P+P*3)%P)%P;
printf("%lld\n",ans);
return 0;
}