一开始一直觉得是搞掉一个
∑
∑
然后用类欧做然后就不会了qaq
看了题解发现跟类欧完全没关系qaq
为了方便以下用[x]代表⌊x⌋
为
了
方
便
以
下
用
[
x
]
代
表
⌊
x
⌋
我们要求这么个东西
给的这个x可以直接当成整数看,小数点后面的东西没用
我们先来考虑确定了
n,m
n
,
m
的子问题
对于拆出来的第一项
如果我们令 d=(n,m) d = ( n , m ) ,那么前面这个东西 ∑m−1k[nkmodm+xm] ∑ k m − 1 [ n k mod m + x m ] 发现他在 mod m m o d m 下有个长度为 md m d 的循环节
那么它就变成了 d∑md−1k=0kdmodm+xm d ∑ k = 0 m d − 1 k d mod m + x m
接着把x也拆出来
两个< m的数加起来< 2m,所以第一项只可能是0或1,于是
d(∑k[kdmodm+xmodm>=m]+x−xmodmm) d ( ∑ k [ k d mod m + x mod m >= m ] + x − x mod m m )
∑k[kdmodm+xmodm>=m] = [xmodmd]
∑
k
[
k
d
mod
m
+
x
mod
m
>=
m
]
=
[
x
mod
m
d
]
,这个式子可以理解成小于等于x的每个
ad(a>0)
a
d
(
a
>
0
)
都能在
kd
k
d
中找到一个
k
k
与之匹配相加>=m,反之同理,那么集合的匹配数就是
[xmodmd]
[
x
mod
m
d
]
又
∑md−1k=0x−xmodmm=x−xmodmd
∑
k
=
0
m
d
−
1
x
−
x
mod
m
m
=
x
−
x
mod
m
d
于是有
也即 d[xd] d [ x d ]
接着化简第二项 ∑m−1k=0nk−nkmodmm ∑ k = 0 m − 1 n k − n k mod m m
=n(m−1)2−dm∑md−1k=0kd
=
n
(
m
−
1
)
2
−
d
m
∑
k
=
0
m
d
−
1
k
d
=n(m−1)−(m−d)2
=
n
(
m
−
1
)
−
(
m
−
d
)
2
那么我们就可以在知道
d
d
的情况下解决这个子问题了
将他带回原问题
就是个简单的反演,推一下, nlogn n l o g n 调和级数暴力预处理一个 f(i) f ( i ) 应该就行了
我当时写的时候中间有一步推错了所以代码处理了两个函数 f(i),g(i) f ( i ) , g ( i ) ,后来改过来仍然没有删掉另一个函数就顺着改一下那样做了,代码不推荐食用
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 510000;
const int mod = 998244353;
inline void add(int &a,const int &b){a+=b;if(a<0)a+=mod;if(a>=mod)a-=mod;}
int pw(int x,int k)
{
int re=1;
for(;k;k>>=1,x=(ll)x*x%mod) if(k&1)
re=(ll)re*x%mod;
return re;
}
int n,m,X,u,inv2;
int p[maxn],pri,mu[maxn];
int sum[maxn],f[maxn],g[maxn];
bool v[maxn];
void pre()
{
mu[1]=1;
for(int i=2;i<=u;i++)
{
if(!v[i]) p[++pri]=i,mu[i]=-1;
for(int j=1,k=p[j]*i;k<=u;j++,k=p[j]*i)
{
v[k]=true;
if(i%p[j]==0) break;
mu[k]=-mu[i];
}
}
for(int i=1;i<=u;i++)
{
int t2=(ll)i*inv2%mod;
int t1=((ll)i*(X/i)%mod+t2)%mod;
for(int j=i,k=1;j<=u;j+=i,k++)
add(f[j],t1*mu[k]),add(g[j],(ll)t2*mu[k]*k%mod);
}
for(int i=1;i<=u;i++) sum[i]=(sum[i-1]+i)%mod;
}
int ans;
int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);
inv2=pw(2,mod-2);
double temp;
scanf("%d%d%lf",&n,&m,&temp); X=(int)temp;
u=max(n,m);
pre();
ans=(ll)m*(m-1)%mod*inv2%mod*inv2%mod*sum[n]%mod;
u=min(n,m);
for(int i=1;i<=u;i++) add(ans,(ll)f[i]*(n/i)%mod*(m/i)%mod);
for(int i=1;i<=u;i++) add(ans,-(ll)g[i]*(n/i)%mod*sum[m/i]%mod);
printf("%d\n",ans);
return 0;
}