题解 P2834 【能力测验】
题意:给定
首先简单容斥,假设
两个式子不相关,考虑分别计算。左边一式长得不好看,首先将
根据取模的定义得到:
又将
有整除分块的样子了。
考虑整理右边的式子。根据定义式将其化为:
也是整除分块的样子。接下来考虑的是
从三次方入手开始降次。写出
我们已经知道了
最后处理出
#include<bits/stdc++.h>
using namespace std;
typedef __int128 LL;
char buf[1<<21],*p1=buf,*p2=buf;
#define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
LL read()
{
LL x=0,f=1;
char c=getchar();
while(c<'0' || c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0'),c=getchar();
return x*f;
}
void write(LL x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const LL MOD=1000000007,inv2=500000004,inv6=166666668;
LL line(LL p){return p*(p+1)/2;}
LL square(LL p){return p*(p+1)*(2*p+1)/6;}
LL n,m;
int main(){
n=read(),m=read();
if(n>m) n^=m^=n^=m;
LL a=0;
for(LL l=1,r;l<=n;l=r+1)
{
r=n/(n/l);
a+=(n/l)*(line(r)-line(l-1));
}
a=n*n-a;
LL b=0;
for(LL l=1,r;l<=m;l=r+1)
{
r=m/(m/l);
b+=(m/l)*(line(r)-line(l-1));
}
b=m*m-b;
LL c=n*m*n;
LL k=0;
for(LL l=1,r;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
r=min(r,n);
k+=(n/l)*(line(r)-line(l-1));
}
c-=k*m;
k=0;
for(LL l=1,r;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
r=min(r,n);
k+=(m/l)*(line(r)-line(l-1));
}
c-=k*n;
k=0;
for(LL l=1,r;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
r=min(r,n);
k+=(n/l)*(m/l)*(square(r)-square(l-1));
}
c+=k;
LL res=a*b-c;
res%=MOD;
res+=MOD;
res%=MOD;
write(res);
return 0;
}