zoukankan      html  css  js  c++  java
  • 【bzoj3309】DZY Loves Math 莫比乌斯反演+线性筛

    Description

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

    Input

    第一行一个数T,表示询问数。
    接下来T行,每行两个数a,b,表示一个询问。

    Output

    对于每一个询问,输出一行一个非负整数作为回答。

    Sample Input

    4
    7558588 9653114
    6514903 4451211
    7425644 1189442
    6335198 4957

    Sample Output

    35793453939901
    14225956593420
    4332838845846
    15400094813

    HINT

    T<=10000
    1<=a,b<=10^7

    sol

    先推式子,假设a<b,枚举gcd:

    (ans=sum_{i=1}^{a}sum_{j=1}^{b}f(i,j))

    (=sum_{d=1}^{a}f(d)sum_{i=1}^{lfloorfrac{a}{d} floor}sum_{j=1}^{lfloorfrac{b}{d} floor}[(i,j)=1])

    (=sum_{d=1}^{a}f(d)sum_{i=1}^{lfloorfrac{a}{d} floor}mu(i)lfloorfrac{a}{id} floorlfloorfrac{b}{id} floor)

    (=sum_{T=1}^{a}lfloorfrac{a}{T} floorlfloorfrac{b}{T} floorsum_{d|T}f(d)mu(frac{T}{d}))

    前面那个玩意直接数论分块就可以了,然后分析后面的式子:

    我们只考虑没有平方因子的T/d,那么此时f(d)的取值只有两种:T最高次质因数幂-1或者T最高次质因数幂。

    如果取的是最高次质因数幂,那么我们发现,T/d中剩下的数字次数可以是0也可以是1,那么根据莫比乌斯函数的定义,(mu(frac{T}{d}))一定等于0,不会产生任何贡献。

    如果取的是最高次质因数幂-1,那么我们发现,满足最高次幂的指数在T/d中都是1次项,其他数字随意,根据莫比乌斯函数的定义,mu一定是0,不会产生任何贡献。

    所以现在只剩下了两种情况:1.质数2.d中所有次幂都相等

    线性筛即可,线性筛处理出每个数字最高次质因数幂和最高次质因数幂的乘积,便可以在线性筛中直接判断。

    code

    #include <bits/stdc++.h>
    using namespace std;
    int g[10000007],a[10000007],pri[10000007],vis[10000007],sum[10000007],ma[10000007],T,n,m,tot;
    long long cal(int a,int b)
    {
    	if(a>b) swap(a,b);
    	long long ans=0;
    	for(int i=1,last=0;i<=a;i=last+1) last=min(a/(a/i),b/(b/i)),ans+=1ll*(a/i)*(b/i)*(sum[last]-sum[i-1]);
    	return ans;
    }
    int main()
    {
    	for(int i=2;i<=1e7;i++)
    	{
    		if(!vis[i]){pri[++tot]=i;g[i]=1,a[i]=1;ma[i]=i;}
    		for(int j=1,k;j<=tot&&(k=i*pri[j])<=1e7;j++)
    		{
    			vis[k]=1;
    			if(i%pri[j]==0)
    			{
    				a[k]=a[i]+1;ma[k]=ma[i]*pri[j];
    				if(i==ma[i]) g[k]=1;
    				else g[k]=(a[i/ma[i]]==a[k]?-g[i/ma[i]]:0);
    			}
    			else a[k]=1,ma[k]=pri[j],g[k]=(a[i]==1?-g[i]:0);
    		}
    		sum[i]=sum[i-1]+g[i];
    	}
    	for(scanf("%d",&T);T--;printf("%lld
    ",cal(n,m))) scanf("%d%d",&n,&m);
    }
    
  • 相关阅读:
    Codeforces 120F Spiders
    Codeforces 509C Sums of Digits
    Topcoder SRM 497 DIV2 1000 MakeSquare
    codeforces 22B Bargaining Table
    Codeforces 487B Strip
    Codeforces 132C Logo Turtle
    关闭窗口对话框提示 messagedlg应用和showmodal的使用
    如何让窗口显示在电脑屏幕中间
    delphi项目程序输出编译成应用程序文件
    delphi程序项目创建和保存
  • 原文地址:https://www.cnblogs.com/CK6100LGEV2/p/9393077.html
Copyright © 2011-2022 走看看