码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3309: DZY Loves Math

时间:2018-04-12 22:35:00      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:include   register   玩意儿   strong   long   class   取值   判断   pre   

BZOJ3309: DZY Loves Math

题目大意

定义\(f(n)\)\(n\)所含质因子的最大幂指数。
例如\(f(2^33^25^411^2) = 4\ \) , \(\ f(3^57^3) = 5\),特别的,\(f(1) = 0\)
现在有\(T\)组数据,每组数据输入两个数\(n\ ,\ m\),试求:
\[\sum_{i = 1}^n \sum_{j=1}^m f(\ gcd(i,j)\ )\]
数据范围:\(T \leq 10^4\) ; \(n,m \leq 10^7\)\(\ \ \)原题网址:戳我

题解

报告!我会莫比乌斯反演!
很好同学,那我们就直接跳到这一步吧......
\(N = min(n,m)\),则:
\[ans = \sum_{T = 1}^N \lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor \sum_{d|T} \mu(\frac{T}{d})f(d)\]
显然前面数论分块就可以解决,关键是如何线性筛出这个玩意儿:
\[G(T) = \sum_{d|T} \mu(\frac{T}{d})f(d)\]
显然\(\mu(\frac{T}{d}) = 0\)的时候对答案是没有贡献的。
唯一分解:\(T = p_1^{x_1}p_2^{x_2}...p_k^{x_k}\) ,同理 \(d = p_1^{y_1}p_2^{y_2}...p_k^{y_k}\)
那么根据\(\mu\)的定义,若\(\mu(\frac{T}{d}) \ne 0\)时 , \(x_i - y_i \leq 1\)
我们考虑有贡献的项,分类讨论一下:

  • 存在\(x_i<x_j\)的时候,
    由于\(f(d) = max\{y\}\)\(y_i \leq y_j\),
    所以无论\(y_i\)怎么取,\(f(d)\)的值都是不会变的。
    所以无论\(y\)的取值情况如何,\(f(d)\)都是一个定值
    \(x_i - y_i\)等于 \(0\)\(1\) 时,在\(\mu(\frac{T}{d})\)\(p_i^{x_i-y_i}\)的贡献刚好是相反的(为1和-1)。
    所以无论\(f(d)\)怎么取,
    非最大\(x\)的那些项的贡献都可以一一抵消。所以这种情况下答案一定是 \(0\)

  • 不存在\(x_i < x_j\),即\(x_1=x_2=...x_k\)时:
    先假设所有情况下\(f(d) = x\) , 那么答案就是 \(0\) , 理由见上。
    但是存在一种情况\(f(d) = x-1\) , 就是当所有\(y\)都等于\(x-1\)的时候。
    这个情况下多出来了一个-1,考虑把这个系数减去。
    显然这个系数带\(\mu\)后等于\(-1\times \mu(\frac{T}{d}) = -\mu(p_1p_2...p_k) = (-1)^{k+1}\)
    所以这种情况下答案为\((-1)^{k+1}\)

所以线性筛的时候记录一下最小质因子的幂指数最小值因子的指数次幂
利用递推的思想,
每次得到 除去最小质因子外的数
通过判断 这个数的最小因子幂指数当前最小因子幂指数 是否相等,
就可以判断出当前答案应该是 \(0\) 还是从之前的答案\(G\) 转移。复杂度:\(O(n + T\sqrt{n})\)

实现代码

#include<bits/stdc++.h>
#define RG register
#define IL inline
#define _ 10000007
using namespace std;
 
int n,m,N,low[_],pri[_],js[_],tot; bool Is[_]; long long ans,G[_];
 
IL void Seive(){
    Is[1] = true ; tot = 0 ; G[1] = 0;
    for(RG int i = 2; i <= N; i ++){
        if(!Is[i]) pri[++tot] = i , G[i] = js[i] = 1 , low[i] = i;
        for(RG int j = 1; j <= tot && i * pri[j] <= N; j ++){
            Is[i * pri[j]] = true ;
            if(i % pri[j] == 0){
                low[i * pri[j]] = low[i] * pri[j] ;
                js[i * pri[j]] = js[i] + 1 ;
                if(low[i] == i) G[i * pri[j]] = 1 ;
                else G[i*pri[j]] = (js[i*pri[j]] == js[i/low[i]]) ? - G[i/low[i]] : 0 ;
                break ;
            }
            low[i * pri[j]] = pri[j] ; js[i * pri[j]] = 1 ;
            G[i * pri[j]] = (js[i] == 1) ? -G[i] : 0 ; 
        }
    }
    for(RG int i = 1; i <= N; i ++) G[i] += G[i - 1] ; 
}
 
int main(){
    N = 10000000 ; Seive() ;
    RG int Cat; cin >> Cat ; 
    while(Cat -- ){
        scanf("%d %d\n",&n,&m) ;  N = min(n , m) ;
        ans = 0 ; 
        for(RG int l = 1,r; l <= N; l = r + 1){
            r = min(N , min(n / (n/l) , m / (m/l))) ;
            ans = ans + 1ll * (n / l) * (m / l) * (G[r] - G[l-1]) ; 
        }
        printf("%lld\n" , ans) ; 
    }return 0 ;
}

BZOJ3309: DZY Loves Math

标签:include   register   玩意儿   strong   long   class   取值   判断   pre   

原文地址:https://www.cnblogs.com/GuessYCB/p/8810429.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!