1. 程式人生 > >P2260 [清華集訓2012]模積和

P2260 [清華集訓2012]模積和

說明 CA mage get 技術 gcd 復制 urn 輸出格式

題目背景

數學題,無背景。

題目描述

技術分享圖片

輸入輸出格式

輸入格式:

兩個整數n m

輸出格式:

答案 mod 19940417

輸入輸出樣例

輸入樣例#1: 復制
3 4
輸出樣例#1: 復制
1
輸入樣例#2: 復制
123456 654321
輸出樣例#2: 復制
116430

說明

30%: n,m <= 1000

60%: n,m <= 10^6

100% n,m <= 10^9

技術分享圖片

#include<iostream>
#include<cstdio>
#include<algorithm>
using
namespace std; const int mod=19940417; void exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0; return; } exgcd(b,a%b,y,x); y-=a/b*x; } int getinv(int num) { int x,y; exgcd(num,mod,x,y); return (x%mod+mod)%mod; } long long n,m; long long ans;
long long inv6=getinv(6); long long inv2=getinv(2); long long sum1(long long a) { return ((a*(a+1)%mod)*(2*a+1)%mod)*inv6%mod; } long long sum2(long long l,long long r) { return ((r-l+1)*(l+r)%mod)*inv2%mod; } long long calc(long long bound) { long long res=bound*bound%mod; for(long
long l=1,r;l<=bound;l=r+1) { if(bound/l) r=min(bound,bound/(bound/l)); else r=bound; res-=sum2(l,r)*(bound/l); } return (res+mod)%mod; } void work() { ans=calc(n)*calc(m); ans%=mod; ans-=n*n%mod*m%mod; for(long long l=1,r;l<=n;l=r+1) { if(n/l==0&&m/l==0) r=n; else { if(n/l) r=min(n,n/(n/l)); if(m/l) r=min(r,m/(m/l)); } ans-=(n/l)*(m/l)%mod*(sum1(r)-sum1(l-1))%mod; ans+=sum2(l,r)*(m*(n/l)%mod+n*(m/l)%mod)%mod; ans%=mod; } printf("%lld",(ans+mod)%mod); } int main() { scanf("%lld%lld",&n,&m); if(n>m) swap(n,m); work(); return 0; }

P2260 [清華集訓2012]模積和