P2834-能力测验【数论,整除分块】

版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/89577678

正题

题目链接:https://www.luogu.org/problemnew/show/P2834


题目大意

i = 1 n j = 1 m ( n % i ) ( m % j ) ( i ! = j ) \sum_{i=1}^n\sum_{j=1}^m(n\%i)*(m\%j)*(i!=j)


解题思路

i = 1 n ( n % i ) j = 1 m ( m % j ) i = 1 m i n { n , m } ( n % i ) ( m % i ) \sum_{i=1}^n(n\%i)*\sum_{j=1}^m(m\%j)-\sum_{i=1}^{min\{n,m\}}(n\%i)*(m\%i)
前面的很好求,我们考虑如何求后面的。
单独考虑 i = 1 n ( n % i ) = n 2 i = 1 n n / i i \sum_{i=1}^{n}(n\%i)=n^2-\sum_{i=1}^n\lfloor n/i\rfloor*i
同理 i = 1 m i n { n , m } ( n n / i i ) ( m m / i i ) \sum_{i=1}^{min\{n,m\}}(n-\lfloor n/i\rfloor*i)*(m-\lfloor m/i\rfloor*i)
i = 1 m i n { n , m } n m ( m n / i + n m / i ) i + m / i n / i i 2 \sum_{i=1}^{min\{n,m\}}n*m-(m*\lfloor n/i\rfloor+n*\lfloor m/i\rfloor)*i+\lfloor m/i\rfloor*\lfloor n/i\rfloor*i^2
n m m i n { n , m } i = 1 m i n { n , m } ( m n / i + n m / i ) i m / i n / i i 2 n*m*min\{n,m\}-\sum_{i=1}^{min\{n,m\}}(m*\lfloor n/i\rfloor+n*\lfloor m/i\rfloor)*i-\lfloor m/i\rfloor*\lfloor n/i\rfloor*i^2
然后除了 i 2 i^2 其他用整体分块都好求,之后我们考虑如何求 i = 1 m i n { n , m } i 2 \sum_{i=1}^{min\{n,m\}} i^2

i = 1 m i n { n , m } i 2 = i ( i + 1 ) ( 2 i + 1 ) 6 \sum_{i=1}^{min\{n,m\}} i^2=\frac{i*(i+1)*(2*i+1)}{6}

数学归纳法

i = 1 m i n { n , m } x 2 = x ( x + 1 ) ( 2 x + 1 ) 6 \sum_{i=1}^{min\{n,m\}} x^2=\frac{x*(x+1)*(2*x+1)}{6}
( i = 1 m i n { n , m } x 2 ) + ( x + 1 ) 2 = x ( x + 1 ) ( 2 x + 1 ) 6 + ( x + 1 ) 2 (\sum_{i=1}^{min\{n,m\}} x^2)+(x+1)^2=\frac{x*(x+1)*(2*x+1)}{6}+(x+1)^2
= > ( x + 1 ) ( 2 x 2 + x ) + 6 ( x + 1 ) 2 6 =>\frac{(x+1)*(2*x^2+x)+6(x+1)^2}{6}
= > ( x + 1 ) ( 2 x 2 + 7 x + 6 ) 6 =>\frac{(x+1)*(2*x^2+7x+6)}{6}
= > ( x + 1 ) ( x + 2 ) ( 2 x + 3 ) 6 =>\frac{(x+1)*(x+2)*(2*x+3)}{6}
= > ( x + 1 ) ( x + 2 ) ( 2 ( x + 1 ) + 1 ) 6 =>\frac{(x+1)*(x+2)*(2*(x+1)+1)}{6}

证毕


c o d e code

#include<cstdio>
#include<algorithm>
#define ll long long
#define sum(l,r) ((l+r)*(r-l+1)/2)
using namespace std;
const int XJQ=1e9+7;
ll n,m,ans;
ll Qs(ll n,ll k)
{
    ll ans=0;
    for(ll x=1,gx;x<=min(n,k);x=gx+1){
        gx=min(k/(k/x),n);
        (ans+=(k/x)*sum(x,gx)%XJQ)%=XJQ;
    }
    return ans%XJQ;
}
ll lx(ll x)
{
    return x*(x+1)%XJQ*(2*x+1)%XJQ*166666668%XJQ;
} 
int main()
{
    scanf("%lld%lld",&n,&m);
    if(m>n) swap(n,m);
    ans=(n*n-Qs(n,n))%XJQ;
    ans=(m*m-Qs(m,m))%XJQ*ans%XJQ;
    ans=(ans+Qs(m,m)*n%XJQ)%XJQ;
    ans=(ans+Qs(m,n)*m%XJQ)%XJQ;
    ans=(ans-m*m%XJQ*n%XJQ+XJQ)%XJQ;
    int tmp=0;
    for(ll i=1,dn,dm,next;i<=m;i=next+1){
        dm=m/i;
        dn=n/i;
        next=min(n/dn,m/dm);
        (tmp+=(lx(next)-lx(i-1))*dn%XJQ*dm%XJQ)%=XJQ;
    }
    printf("%lld",(ans-tmp+XJQ)%XJQ);
}

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/89577678