知味 2018-01-04
t<=1e4个询问每次问n,m<=1e7,$\sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m}lcm(x,y)$。
首先题目要求的是$\sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m}lcm(x,y)=\sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m}\frac{x*y}{(x,y)}$,
啊很好那来枚举gcd吧,$\sum_{t=1}^{min(n,m)} t^{-1} f(t)$,其中$f(t)=\sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m,(x,y)=t} x*y$,哦太棒了来反演吧。
套路三:反演个鬼啊先化一化:$f(t)=t*t*\sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m,(x,y)=1} x*y$。
好来演$g(t)=\sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m}xy=\frac{x*(x+1)}{2}\frac{y*(y+1)}{2}$,$f(t)=t*t*\sum_{1\leqslant d\leqslant t}\mu(d)\frac{n}{d}\frac{m}{d}$。
代进去!前后枚举约数和除数暴力算即可。$\sqrt n * \sqrt n$=O(n)搞定。
套路三就是反演之前冷静一下变个型啦。
套路四:化个鬼啊直接反演:$\sum_{t=1}^{min(n,m)} t^{-1} \sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m,(x,y)=t} x*y =\sum_{t=1}^{min(n,m)} t^{-1} \sum_{t|d} \mu(\frac{d}{t}) \sum_{1\leqslant x\leqslant n,1\leqslant y\leqslant m,d|(x,y)} x*y=\sum_{t=1}^{min(n,m)} t^{-1} \sum_{t|d} \mu(\frac{d}{t}) * d^2 * \frac{(1+\frac{n}{d})\frac{n}{d}}{2} \frac{(1+\frac{m}{d})\frac{m}{d}}{2}=\sum_{t=1}^{min(n,m)}\sum_{t|d} \mu(\frac{d}{t})* \frac{d}{t} * d *\frac{(1+\frac{n}{d})\frac{n}{d}}{2} \frac{(1+\frac{m}{d})\frac{m}{d}}{2} = \sum_{d=1}^{min(n,m)}\frac{(1+\frac{n}{d})\frac{n}{d}}{2} \frac{(1+\frac{m}{d})\frac{m}{d}}{2} * d * \sum_{t|d} \mu(t) * t$。
漂亮!前面一坨可以根号枚举,如果能得到线性得到所有$d * \sum_{t|d} \mu(t) * t$就可以了。先不*d,这东西不是个积性函数么?(打表可知,易证)
线性筛筛出来然后记个前缀和,就可以$O(n)$预处理,然后$O(\sqrt n)$回答每个询问了。


1 //#include<iostream>
2 #include<cstring>
3 #include<cstdlib>
4 #include<cstdio>
5 //#include<bitset>
6 #include<algorithm>
7 //#include<cmath>
8 using namespace std;
9
10 const int mod=20101009;
11 int T,n,m;
12 #define maxn 10000011
13 int inv[maxn],miu[maxn],prime[maxn],sum[maxn],lp; bool notprime[maxn];
14 void pre(int n)
15 {
16 miu[1]=1; lp=0; sum[1]=1;
17 long long tmp;
18 for (int i=2;i<=n;i++)
19 {
20 if (!notprime[i]) {prime[++lp]=i; miu[i]=-1; sum[i]=mod-i+1;}
21 for (int j=1;j<=lp && (tmp=1ll*prime[j]*i)<=n;j++)
22 {
23 notprime[tmp]=1;
24 if (i%prime[j]) miu[tmp]=-miu[i],sum[tmp]=1ll*sum[i]*sum[prime[j]]%mod;
25 else {miu[tmp]=0; sum[tmp]=sum[i]; break;}
26 }
27 }
28 for (int i=2;i<=n;i++) sum[i]=1ll*sum[i]*i%mod,sum[i]+=sum[i-1],sum[i]-=sum[i]>=mod?mod:0;
29 // for (int i=1;i<=n;i++) cout<<sum[i]<<' ';cout<<endl;
30 }
31
32 int main()
33 {
34 scanf("%d%d",&n,&m);
35 pre(min(n,m));
36 // scanf("%d",&T);
37 //while (T--)
38 //{
39 int ans=0;
40 for (int i=1,to=min(n,m),last,hh=((mod+1)>>1)*1ll*((mod+1)>>1)%mod;i<=to;i=last+1)
41 {
42 last=min(n/(n/i),m/(m/i));
43 ans+=1ll*(n/i)*(m/i)%mod*(1+(n/i))%mod*(1+(m/i))%mod*hh%mod*(sum[last]-sum[i-1])%mod;
44 ans-=ans>=mod?mod:0,ans+=ans<0?mod:0;
45 }
46 printf("%d\n",ans);
47 //}
48 return 0;
49 }View Code