BZOJ 2956 模积和

Problem

BZOJ请戳我

Solution

i=1nj=1,ijm(nmodi)(mmodj)=i=1n(nmodi)j=1m(mmodj)i=1min(n,m)(nmodi)(mmodi)=i=1n(nmodi)j=1m(mmodj)I=1min(n,m)(nnii)(mmii)=i=1n(nmodi)j=1m(mmodj)I=1min(n,m)(nm+nimii2(mni+nmi)i) ∑ i = 1 n ∑ j = 1 , i ≠ j m ( n mod i ) ( m mod j ) = ∑ i = 1 n ( n mod i ) ∗ ∑ j = 1 m ( m mod j ) − ∑ i = 1 m i n ( n , m ) ( n mod i ) ( m mod i ) = ∑ i = 1 n ( n mod i ) ∗ ∑ j = 1 m ( m mod j ) − ∑ I = 1 m i n ( n , m ) ( n − ⌊ n i ⌋ i ) ( m − ⌊ m i ⌋ i ) = ∑ i = 1 n ( n mod i ) ∗ ∑ j = 1 m ( m mod j ) − ∑ I = 1 m i n ( n , m ) ( n m + ⌊ n i ⌋ ⌊ m i ⌋ i 2 − ( m ⌊ n i ⌋ + n ⌊ m i ⌋ ) i )

前半部分同CQOI2007余数求和分块做一下,后半部分同样也是分块。然后 ni=1i2=n(n+1)(2n+1)6 ∑ i = 1 n i 2 = n ∗ ( n + 1 ) ∗ ( 2 ∗ n + 1 ) 6 ,6在模19940417意义下的逆元是3323403。

Code

#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll mod=19940417;
ll n,m,ans,a,b,c;
inline ll min(ll x,ll y){return x<y?x:y;}
inline ll sum(ll l,ll r){return ((l+r)*(r-l+1)/2)%mod;}
inline ll sqr(ll x){return x*(x+1)%mod*(x<<1|1)%mod*3323403%mod;}
ll check(ll n)
{
    ll res=n*n%mod;
    for(int i=1,j;i<=n;i=j+1)
    {
        j=n/(n/i);
        res=(res-(sum(i,j)*(n/i))+mod)%mod;
    }
    return res;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    scanf("%lld%lld",&n,&m);
    ans=(check(n)*check(m))%mod;
    if(n>m) swap(n,m);
    for(int i=1,j;i<=n;i=j+1)
    {
        j=min(n/(n/i),m/(m/i));
        a=n*m%mod*(j-i+1)%mod;
        b=(m*(n/i)%mod+n*(m/i)%mod)%mod*sum(i,j)%mod;
        c=(n/i)*(m/i)%mod*((sqr(j)-sqr(i-1)+mod)%mod)%mod;
        ans=(ans-a+b-c+mod+mod)%mod;
    }
    printf("%lld\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值