bzoj4407 于神之怒加强版

Description

Input

多组数据。
第一行是两个数T,K;
之后的T行,每行两个整数n,m;

Output

T行,每行一个结果

Sample Input

1 2
3 3

Sample Output

20

Hint

T<=2000,1<=N,M,K<=5000000

 

正解:莫比乌斯函数。

一顿乱推。。

$Ans=\sum_{i=1}^{n}\sum_{j=1}^{m}\gcd(i,j)^{k}$

$Ans=\sum_{d=1}^{min(n,m)}d^{k}\sum_{i=1}^{n}\sum_{j=1}^{m}[\gcd(i,j)==d]$

然后推到$Ans=\sum_{d=1}^{min(n,m)}d^{k}\sum_{p=1}^{min(\frac{n}{d},\frac{m}{d})}\mu(p)\left \lfloor \frac{n}{dp} \right \rfloor\left \lfloor \frac{m}{dp} \right \rfloor$

令$Q=dp$,$Ans=\sum_{Q=1}^{min(n,m)}\left \lfloor \frac{n}{Q} \right \rfloor\left \lfloor \frac{m}{Q} \right \rfloor\sum_{d|Q}d^{k}\mu(\frac{Q}{d})$

令$f(Q)=\sum_{d|Q}d^{k}\mu(\frac{Q}{d})$,我们发现,因为$d^{k}$是个积性函数,$\mu$也是个积性函数,于是根据狄利克雷卷积的性质,$f(Q)$也是个积性函数。

然后我们打表找规律,发现当$i$为质数时,$f(i)=i^{k}-1$;当$i mod prime[j]=0$时,$f(i*prime[j])=f(i)*prime[j]^{k}$。

于是我们就能线性筛出$f(i)$,然后求出前缀和,运用数论分块,我们可以将复杂度降至$O(\sqrt{n}T)$。于是,这道题就被顺利解决了。

 

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <complex>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cmath>
10 #include <queue>
11 #include <stack>
12 #include <map>
13 #include <set>
14 #define inf (1<<30)
15 #define N (5000010)
16 #define il inline
17 #define RG register
18 #define ll long long
19 #define rhl (1000000007)
20 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
21 
22 using namespace std;
23 
24 int vis[N],prime[N],T,k,n,m,cnt,pos;
25 ll bin[N],mu[N],f[N],ans;
26 
27 il int gi(){
28     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
29     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
30 }
31 
32 il ll qpow(RG ll a,RG ll b){
33     RG ll ans=1;
34     while (b){
35     if (b&1) ans=ans*a; a=a*a,b>>=1;
36     if (ans>=rhl) ans%=rhl;
37     if (a>=rhl) a%=rhl;
38     }
39     return ans;
40 }
41 
42 il void sieve(){
43     vis[1]=mu[1]=f[1]=bin[1]=1;
44     for (RG int i=2;i<N;++i){
45     if (!vis[i]) vis[i]=1,mu[i]=rhl-1,bin[i]=qpow(i,k),f[i]=(bin[i]+rhl-1)%rhl,prime[++cnt]=i;
46     for (RG int j=1,k=i*prime[j];j<=cnt && k<N;++j,k=i*prime[j]){
47         vis[k]=1;
48         if (i%prime[j]) mu[k]=rhl-mu[i],f[k]=f[i]*f[prime[j]]%rhl;
49         else{ f[k]=f[i]*bin[prime[j]]%rhl; break; }
50     }
51     }
52     for (RG int i=2;i<N;++i){
53     mu[i]+=mu[i-1],f[i]+=f[i-1];
54     if (mu[i]>=rhl) mu[i]-=rhl;
55     if (f[i]>=rhl) f[i]-=rhl;
56     }
57     return;
58 }
59 
60 il void work(){
61     n=gi(),m=gi(),ans=0; if (n>m) swap(n,m);
62     for (RG int i=1;i<=n;i=pos+1){
63     pos=min(n/(n/i),m/(m/i));
64     ans+=(ll)(n/i)*(ll)(m/i)%rhl*(f[pos]-f[i-1]+rhl)%rhl;
65     if (ans>=rhl) ans-=rhl;
66     }
67     printf("%lld\n",ans); return;
68 }
69 
70 int main(){
71     File("4407");
72     T=gi(),k=gi(),sieve();
73     while (T--) work();
74     return 0;
75 }

 

posted @ 2017-03-16 11:36  wfj_2048  阅读(167)  评论(0编辑  收藏  举报