多组数据,每行两个数N,M(1 <= N,M <= 100000)。
5 5 1 3
19 55 55 3 3 6
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 typedef long long LL; 7 8 const int maxn = 1e5+3; 9 bool s[maxn]; 10 int prime[maxn],len = 0; 11 int mu[maxn]; 12 LL hxl [maxn]; 13 int sum1[maxn]; 14 void init() 15 { 16 memset(s,true,sizeof(s)); 17 mu[1] = 1; 18 for(int i=2;i<maxn;i++) 19 { 20 if(s[i] == true) 21 { 22 prime[++len] = i; 23 mu[i] = -1; 24 } 25 for(int j=1;j<=len && (long long)prime[j]*i<maxn;j++) 26 { 27 s[i*prime[j]] = false; 28 if(i%prime[j]!=0) 29 mu[i*prime[j]] = -mu[i]; 30 else 31 { 32 mu[i*prime[j]] = 0; 33 break; 34 } 35 } 36 } 37 for(int i=1;i<maxn;i++) 38 sum1[i] = sum1[i-1]+mu[i]; 39 hxl[1] = mu[1]; 40 for(int i=2;i<maxn;i++){ 41 hxl[i] = i*mu[i]+hxl[i-1]; 42 } 43 } 44 int main() 45 { 46 init(); 47 int n,m; 48 while(scanf("%d%d",&n,&m)>0) 49 { 50 LL sum = 0; 51 LL ansi = 0,ansj = 0; 52 int a = n; 53 int b = m; 54 if(a>b) swap(a,b); 55 for(int i=1,la = 0;i<=a;i++,i = la+1) 56 { 57 la = min(a/(a/i),b/(b/i)); 58 sum = sum + ((LL)(a/i))*(b/i)*(sum1[la]-sum1[i-1]); 59 ansi = ansi +(hxl[la]-hxl[i-1])*(((LL)(n/i+1)*(n/i))/2)*(m/i); 60 ansj = ansj +(hxl[la]-hxl[i-1])*(((LL)(m/i+1)*(m/i))/2)*(n/i); 61 } 62 printf("%lld %lld %lld\n",sum,ansi,ansj); 63 } 64 return 0; 65 }