洛谷题目传送门
BZOJ题目传送门
推式子:
减号前面的直接像余数之和一样搞一搞,后面的除法分块算一下就好了。
有一个公式: ∑ni=1i2=n(n+1)(2n+1)6 ∑ i = 1 n i 2 = n ( n + 1 ) ( 2 n + 1 ) 6
代码:
#include
#include
#include
#include
#define inv 3323403
#define MOD 19940417
#define F inline
using namespace std;
typedef long long LL;
LL n,m,ans,p1,p2,p3;
F LL ca(LL x,LL y){ return (y-x+1)*(x+y)/2%MOD; }
F LL cal(LL x){ return x*(x+1)%MOD*(x*2+1)%MOD*inv%MOD; }
F LL calc(LL x){
LL ret=0;
for (LL l=1,r;l<=x;l=r+1)
r=x/(x/l),ret=(ret+x*(r-l+1)%MOD-ca(l,r)*(x/l))%MOD;
return (ret+MOD)%MOD;
}
int main(){
scanf("%lld%lld",&n,&m);
ans=calc(n)*calc(m)%MOD;
if (n>m) swap(n,m);
for (LL l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
p1=n*m%MOD*(r-l+1)%MOD;
p2=(n/l)*(m/l)%MOD;
p2=p2*(cal(r)-cal(l-1)+MOD)%MOD;
p3=(m*(n/l)+n*(m/l))%MOD*ca(l,r)%MOD;
ans=(ans-(p1+p2-p3)%MOD+MOD)%MOD;
}
return printf("%lld\n",ans),0;
}