对于正整数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。
Solution
一开始没仔细看数据范围然后打了一个每个询问O(n)的,当然T了
(盗一张图)
一开始我按照第二行的做的,里层外层循环都和ab有关,每一层都要sqrt(n)
然后发现f(d)和ab无关,于是把f放到里面,把和ab有关的拎出来,就变成了第三行的式子
这样里面一层循环与ab无关,可以预处理好
我们要求的就是后面sigma的前缀和
不难想到nlogn的预处理,但这题比较卡还是T
于是要这么做
设g(T)=Σ[d|T]f(d)μ(T/d)
大力分析
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 }