2019.01.07-bzoj3309: DZY Loves Math-dtoj1669

 题目描述:

对于正整数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)。

算法标签:数论,欧拉函数

思路:

此时预处理出f效率是nlogn还是过不去...真可怕

于是继续化,令T=kd

不妨令

 

对于存在pi!=pj

如果存在p1-q1>=1,则为0,不考虑。

其余对于存在一个的情况,你选定一个最大值,对于最大值相同的取正负号的数量相同,因此权值为0.

对于任意pi==pj的情况,取正负号的方案相同,但是其中一组最大值为p1,不为p1+1所以不能完全消去,因此获得的权值

线性筛预处理出f,然后每次log求出答案即可。

以下代码:

#include<bits/stdc++.h>
#define il inline
#define _(d) while(d(isdigit(ch=getchar())))
using namespace std;
const int N=1e7,M=1e7+5;
int mx[M],num[M],pri[N],g[M],tot;bool vis[M];
il int read(){int x;char ch;_(!);x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return x;}
il void init(){
    for(int i=2;i<=N;i++){
        if(!vis[i])pri[++tot]=i,vis[i]=1,mx[i]=i,num[i]=1,g[i]=1;
        for(int j=1;j<=tot&&pri[j]*i<=N;j++){
            vis[i*pri[j]]=1;
            if(i%pri[j]==0){
                num[pri[j]*i]=num[i]+1;
                mx[i*pri[j]]=mx[i]*pri[j];
                int tmp=i/mx[i];
                if(tmp==1)g[i*pri[j]]=1;
                else g[i*pri[j]]=(num[tmp]==num[i*pri[j]])?-g[tmp]:0;
                break;
            }
            mx[i*pri[j]]=pri[j];num[i*pri[j]]=1;g[i*pri[j]]=(num[i]==1)?-g[i]:0;
        }
    }
    for(int i=2;i<=N;i++)g[i]+=g[i-1];
}
int main()
{
    init();int T=read();
    while(T--){
        int a=read(),b=read();int pos;long long ans=0;
        for(int i=1;i<=min(a,b);i=pos+1){
            pos=min(a/(a/i),b/(b/i));
            ans+=1ll*(g[pos]-g[i-1])*(a/i)*(b/i);
        }
        printf("%lld
",ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Jessie-/p/10236538.html