對於正整數n,定義f(n)爲n所含質因子的最大冪指數。例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0。
給定正整數a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b)。T<=1e4; a,b<=1e7。spa
Solution
一開始沒仔細看數據範圍而後打了一個每一個詢問O(n)的,固然T了code
(盜一張圖)blog
一開始我按照第二行的作的,裏層外層循環都和ab有關,每一層都要sqrt(n)ip
而後發現f(d)和ab無關,因而把f放到裏面,把和ab有關的拎出來,就變成了第三行的式子get
這樣裏面一層循環與ab無關,能夠預處理好string
咱們要求的就是後面sigma的前綴和it
不難想到nlogn的預處理,但這題比較卡仍是Tio
因而要這麼作ast
設g(T)=Σ[d|T]f(d)μ(T/d)class
大力分析
1 #include<cstdio>
2 #include<algorithm>
3 #include<cstring>
4 #define ll long long
5 using namespace std;
6 const int maxn=1e7+5;
7
8 bool flag[maxn]; int prime[maxn],cnt;
9 int t[maxn],last[maxn],g[maxn];
10 int n,m;
11
12 void getmu(){
13 for(int i=2;i<=1e7;i++){
14 if(!flag[i]){
15 prime[++cnt]=i;
16 last[i]=t[i]=1;
17 g[i]=1;
18 }
19 for(int j=1;i*prime[j]<=1e7&&j<=cnt;j++){
20 int x=i*prime[j];
21 flag[x]=1;
22 if(i%prime[j]==0){
23 last[x]=last[i];
24 t[x]=t[i]+1;
25 if(last[x]==1)
26 g[x]=1;
27 else
28 g[x]=(t[last[x]]==t[x]?-g[last[x]]:0);
29 break;
30 }
31 last[x]=i;
32 t[x]=1;
33 g[x]=(t[i]==1?-g[i]:0);
34 }
35 }
36 for(int i=1;i<=1e7;i++)
37 g[i]+=g[i-1];
38 }
39
40 ll f(int x,int y){
41 ll ret=0;
42 for(int i=1,pos=1;i<=x;i=pos+1){
43 pos=min(x/(x/i),y/(y/i));
44 ret+=1ll*(g[pos]-g[i-1])*(x/i)*(y/i);
45 }
46 return ret;
47 }
48
49 int main(){
50 getmu();
51
52 int T;
53 scanf("%d",&T);
54 while(T--){
55 scanf("%d%d",&n,&m);
56 if(n>m) swap(n,m);
57 printf("%lld\n",f(n,m));
58 }
59 return 0;
60 }