【莫比乌斯反演】BZOJ4174 tty的求助

【题目】
原题地址
∑ n = 1 N ∑ m = 1 M ∑ k = 0 m − 1 ⌊ n k + x m ⌋   m o d   998244353 \sum_{n=1}^N\sum_{m=1}^M\sum_{k=0}^{m-1}\lfloor\frac{nk+x}m\rfloor\ mod\ 998244353 n=1Nm=1Mk=0m1mnk+x mod 998244353

【题目分析】
有下取整的东西并没有见过qwq,大概试着化了一下,没有见过这种技巧很难做出来。

【解题思路】
根据popoqqq的说法,如果我们知道 n n n m m m,我们要求的东西等价于:
∑ k = 0 m − 1 ⌊ n k + x m ⌋ \sum_{k=0}^{m-1}\lfloor\frac{nk+x}m\rfloor k=0m1mnk+x
= ∑ k = 0 m − 1 ( ⌊ n k % m + x m ⌋ + n k − n k % m m ) =\sum_{k=0}^{m-1}(\lfloor\frac{nk\%m+x}m\rfloor+\frac{nk-nk\%m}m) =k=0m1(mnk%m+x+mnknk%m)
= ∑ k = 0 m − 1 ( ⌊ n k % m + x m ⌋ + n k m − n k % m m ) =\sum_{k=0}^{m-1}(\lfloor\frac{nk\%m+x}m\rfloor+\frac{nk}m-\frac{nk\%m}m) =k=0m1(mnk%m+x+mnkmnk%m)

那么这个柿子是可以拆开每一项来考虑的,后面两项的结构比较简单,重点在第一个带x的柿子。
d = g c d ( n , m ) d=gcd(n,m) d=gcd(n,m),则:
∑ k = 0 m − 1 ( ⌊ n k % m + x m ⌋ ) \sum_{k=0}^{m-1}(\lfloor\frac{nk\%m+x}m\rfloor) k=0m1(mnk%m+x)
= d ∗ ∑ k = 0 m d − 1 ⌊ k d + x m ⌋ =d*\sum_{k=0}^{\frac md-1}\lfloor\frac{kd+x}m\rfloor =dk=0dm1mkd+x
= d ∗ ( m d ∗ x − x % m m + ∑ k = 0 m d − 1 ⌊ k d + x % m m ⌋ ) =d*(\frac md*\frac{x-x\%m}m+\sum_{k=0}^{\frac md-1}\lfloor\frac{kd+x\%m}m\rfloor) =d(dmmxx%m+k=0dm1mkd+x%m)
= d ∗ ( m d ∗ x − x % m m + ∑ k = 0 m d − 1 [ k d + x % m ≥ m ] ) =d*(\frac md*\frac{x-x\%m}m+\sum_{k=0}^{\frac md-1}[kd+x\%m\geq m]) =d(dmmxx%m+k=0dm1[kd+x%mm])
= d ∗ ( x − x % m d + ⌊ x % m d ⌋ ) =d*(\frac{x-x\%m}d+\lfloor\frac{x\%m}d\rfloor) =d(dxx%m+dx%m)
= d ∗ ⌊ x d ⌋ =d*\lfloor\frac xd\rfloor =ddx

倒数第三步的原因是 k d kd kd x % m x\%m x%m都小于 m m m,因此取值只能是0或1.
上面的倒数第二步的后面一项我看了挺久才看懂qwq,我太菜了。
其实这步要求,的就是 k d + x % m ≥ m kd+x\%m\geq m kd+x%mm的数量,那么移项可以得到 x % m ≥ m − k d x\% m \geq m-kd x%mmkd,即 ⌊ x % m d ⌋ ≥ m d − k \lfloor \frac {x\% m} d \rfloor \geq \frac m d -k dx%mdmk,因为 k k k [ 0 , m d − 1 ] [0,\frac m d -1] [0,dm1],所以实际上 ⌊ x % m d ⌋ \lfloor \frac {x\% m} d \rfloor dx%m就是满足不等式的 k k k数目。

其余的两项通过推导分别可以得到:
∑ k = 0 m − 1 n k m = n m ∗ m ∗ ( m − 1 ) 2 = n ∗ m − n 2 \sum_{k=0}^{m-1}\frac{nk}m=\frac nm*\frac{m*(m-1)}2=\frac{n*m-n}2 k=0m1mnk=mn2m(m1)=2nmn
∑ k = 0 m − 1 n k % m m = d ∗ ∑ k = 0 m d − 1 k d m = d 2 m ∗ ( m d − 1 ) ∗ m d 2 = m − d 2 \sum_{k=0}^{m-1}\frac{nk\%m}m=d*\sum_{k=0}^{\frac md-1}\frac{kd}m=\frac{d^2}m*\frac{(\frac md-1)*\frac md}2=\frac{m-d}2 k=0m1mnk%m=dk=0dm1mkd=md22(dm1)dm=2md

那么最终的答案就是:
∑ n = 1 N ∑ m = 1 M ( d ∗ ⌊ x d ⌋ + n ∗ m − n 2 − m − d 2 ) \sum_{n=1}^N\sum_{m=1}^M(d*\lfloor\frac xd\rfloor+\frac{n*m-n}2-\frac{m-d}2) n=1Nm=1M(ddx+2nmn2md)
= 1 2 ∗ ∑ n = 1 N ∑ m = 1 M ( 2 ∗ d ∗ ⌊ x d ⌋ + d + n ∗ m − n − m ) =\frac12*\sum_{n=1}^N\sum_{m=1}^M(2*d*\lfloor\frac xd\rfloor+d+n*m-n-m) =21n=1Nm=1M(2ddx+d+nmnm)
= 1 2 ∗ ( S ( N ) ∗ S ( M ) − S ( N ) ∗ m − S ( M ) ∗ n + ∑ d = 1 m i n ( N , M ) ( d + 2 ∗ d ∗ ⌊ x d ⌋ ) ∑ k = 1 m i n ( ⌊ N d ⌋ , ⌊ M d ⌋ ) μ ( k ) ∗ ⌊ N d ∗ k ⌋ ∗ ⌊ M d ∗ k ⌋ ) =\frac12*(S(N)*S(M)-S(N)*m-S(M)*n+\sum_{d=1}^{min(N,M)}(d+2*d*\lfloor\frac xd\rfloor)\sum_{k=1}^{min(\lfloor\frac Nd\rfloor,\lfloor\frac Md\rfloor)}\mu(k)*\lfloor\frac N{d*k}\rfloor*\lfloor\frac M{d*k}\rfloor) =21(S(N)S(M)S(N)mS(M)n+d=1min(N,M)(d+2ddx)k=1min(dN,dM)μ(k)dkNdkM)
其中 S ( x ) = x ∗ ( x + 1 ) 2 S(x)=\frac {x*(x+1)} 2 S(x)=2x(x+1)
O ( n l o g n ) O(nlogn) O(nlogn)枚举 d d d k k k即可。

【参考代码】

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const LL mod=998244353;
const int N=5e5+10;
int n,m,x,pnum,mu[N],bo[N],pri[N];
LL ans;

void init()
{
	mu[1]=1;
	for(int i=2;i<N;++i)
	{
		if(!bo[i]) pri[++pnum]=i,mu[i]=mod-1;
		for(int j=1;j<=pnum && pri[j]*i<N;++j)
		{
			bo[i*pri[j]]=1;
			if(!(i%pri[j])) {mu[i*pri[j]]=0;break;}
			mu[i*pri[j]]=(mod-mu[i])%mod;
		}
	}
}

LL sum(LL x) {return (x*(x+1)/2ll)%mod;}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("BZOJ4174.in","r",stdin);
	freopen("BZOJ4174.out","w",stdout);
#endif	
	init();
	scanf("%d%d%d",&n,&m,&x);if(n>m) swap(n,m);
	ans=((sum(n)*sum(m)-sum(n)*m-sum(m)*n)%mod+mod)%mod;
	for(int i=1;i<=n;++i)
	{
		LL tmp=i+x/i*i*2;
		for(int j=1;i*j<=n;++j) (ans+=tmp*mu[j]%mod*(n/i/j)%mod*(m/i/j)%mod)%=mod;
	}
	printf("%lld\n",(ans*((mod+1)/2ll))%mod);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值