#整除分块#洛谷 2260 模积和 洛谷 2834 能力测验

博客介绍了如何使用整除分块方法解决洛谷2260题目的模积和问题,以及在洛谷2834能力测验中的类似计算。通过容斥原理,将原问题转化为求和公式,并利用数论技巧简化表达式。最后,博主给出了具体的代码实现。

题目

∑i=1n∑j=1m(n mod i)×(m mod j),i≠j\sum_{i=1}^{n} \sum_{j=1}^{m} (n \bmod i) \times (m \bmod j), i \neq ji=1nj=1m(nmodi)×(mmodj),i̸=j


分析

首先这个东西需要容斥
=∑i=1n∑j=1m(n mod i)×(m mod j)−∑i=1min(n,m)(n mod i)(m mod i)=\sum_{i=1}^{n} \sum_{j=1}^{m} (n \bmod i) \times (m \bmod j)-\sum_{i=1}^{min(n,m)}(n\bmod i)(m\bmod i)=i=1nj=1m(nmodi)×(mmodj)i=1min(n,m)(nmodi)(mmodi)
首先前面这个东西
=∑i=1n(n mod i)∑j=1m(m mod j)−∑i=1min(n,m)(n mod i)(m mod i)=\sum_{i=1}^{n} (n \bmod i) \sum_{j=1}^{m} (m \bmod j)-\sum_{i=1}^{min(n,m)}(n\bmod i)(m\bmod i)=i=1n(nmodi)j=1m(mmodj)i=1min(n,m)(nmodi)(mmodi)
前面这个东西可以想起余数求和那道题,所以说只剩下后面,后面先把a mod ba \bmod bamodb改成a−⌊ab⌋∗ba-\lfloor\frac{a}{b}\rfloor*babab
后式=∑i=1min(n,m)(n−⌊ni⌋∗i)(m−⌊mi⌋∗i)\sum_{i=1}^{min(n,m)}(n-\lfloor\frac{n}{i}\rfloor*i)(m-\lfloor\frac{m}{i}\rfloor*i)i=1min(n,m)(nini)(mimi),也就是
=∑i=1min(n,m)(nm−i(⌊ni⌋m+⌊mi⌋n)+i2⌊ni⌋⌊mi⌋)=\sum_{i=1}^{min(n,m)}(nm-i(\lfloor\frac{n}{i}\rfloor m+\lfloor\frac{m}{i}\rfloor n)+i^2\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{i}\rfloor)=i=1min(n,m)(nmi(inm+imn)+i2inim)
然后∑i=1ni2=n(n+1)(2n+1)/6\sum_{i=1}^ni^2=n(n+1)(2n+1)/6i=1ni2=n(n+1)(2n+1)/6,最可怕的是,可能不是质数,所以嗯。


代码(模积和)

#include <cstdio>
#define rr register
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const ll mod=19940417;
ll n,m,ans;
inline ll answ1(ll n){
    rr ll ans=n*n%mod;
    for (rr ll l=1,r;l<=n;l=r+1)
        r=n/(n/l),ans=(ans-(n/l)*((l+r)*(r-l+1)>>1)%mod)%mod;
    return (ans+mod)%mod;
}
inline ll answ2(ll n){
    return n*(n+1)%mod*(n<<1|1)%mod*3323403%mod;
}
signed main(){
    scanf("%lld%lld",&n,&m);
    if (n>m) n^=m,m^=n,n^=m;
    ans=answ1(n)*answ1(m)%mod;
    for (rr ll l=1,r;l<=n;l=r+1){
        rr ll fir,sec,thi;
        r=min(n/(n/l),m/(m/l));
        fir=n*m%mod*(r-l+1)%mod;
        sec=(n/l)*(m/l)%mod*(answ2(r)-answ2(l-1)+mod)%mod;
        thi=(n/l*m+m/l*n)%mod*(((l+r)*(r-l+1)>>1)%mod)%mod;
        ans=(ans-fir-sec+thi)%mod;
    }
    return !printf("%lld",(ans+mod)%mod);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值