zoukankan      html  css  js  c++  java
  • [BZOJ2693]:jzptab

    Description

    (sum_{i=1}^{n}sum_{j=1}^{m}{lcm(i,j)})

    Input

    一个正整数T表示数据组数
    接下来T行 每行两个正整数 表示N、M

    Output

    T行 每行一个整数 表示第i组数据的结果

    Sample Input

    1
    4 5

    Sample Output

    122

    HINT

    T <= 10000
    N, M<=10000000


    题解

    抄的
    (sum_{i=1}^{n}sum_{j=1}^{m}{i*j/gcd(i,j)})
    (=sum_{d=1}^{n}sum_{i=1}^{n}sum_{j=1}^{m}{i j / d[gcd(i,j)==d]})
    (sum_{d=1}^{n}sum_{i=1}^{n/d}sum_{j=1}^{m/d}{ijd[gcd(i,j)==1]})
    (sum_{d=1}^{n}dsum_{i=1}^{n/d}sum_{j=1}^{m/d}{ij[gcd(i,j)==1]})

    (x=n/d,y=m/d)
    (f(d)=sum_{i=1}^{x}sum_{j=1}^{y}{ij[gcd(i,j)==d]})
    (F(d)=sum_{i=1}^{x}sum_{j=1}^{y}{ij[d|gcd(i,j)]})
    (F(d)=d^2sum_{i=1}^{x/d}sum_{j=1}^{y/d}{ij})

    那么(Ans=sum_{d=1}^{n}df(1))

    (f(1)=sum_{i=1}^{x}sum_{j=1}^{y}{ij[gcd(i,j)==1]})
    (f(1)=sum_{t=1}^{x}mu(t)F(t))
    (f(1)=sum_{t=1}^{x}mu(t)t^2sum_{i=1}^{x/t}sum_{j=1}^{y/t}{ij})
    (f(1)=sum_{t=1}^{x}mu(t)t^2B(x/t)B(y/t))(其中B(x)=frac{(1 + x) * x}2)
    (Ans=sum_{d=1}^{n}{d}sum_{t=1}^{n/d}mu(t)t^2B(n/dt)B(m/dt))

    然后单独看后头那些东西
    (P(x,y)=sum_{t=1}^{min(x,y)}{mu(t)t^2B(x/t)B(y/t)})
    可以除法分块

    然后(Ans=sum_{d=1}^{min(n,m)}{d}P(n/d,m/d))
    这玩意儿是不是也能除法分块
    所以复杂度就是(O(n))

    然后还能不能化简?

    交换求和号

    (Ans=sum_{T=1}^{n}{B(n/T)B(m/T)sum_{i|T}{mu(i)i^2frac{T}i}})
    这样以后后面的东西是一个积性函数,可以通过线筛求出前缀和
    即可(O(sqrt{n}))回答询问

    代码

    #include<cstdio>
    #include<algorithm>
    # define LL long long
    const int M = 10000005 ;
    const int mod = 100000009 ;
    using namespace std ;
    inline int read() {
    	char c = getchar() ; int x = 0 , w = 1 ;
    	while(c>'9'||c<'0') { if(c=='-') w = -1 ; c = getchar() ; }
    	while(c>='0'&&c<='9') { x = x*10+c-'0' ; c = getchar() ; }
    	return x*w ;
    }
     
    bool notp[M] ;
    int p[M] , pnum , sum[M] ;
    int n , m , Ans , f[M] ;
    void Get_Sum(int n) {
        sum[1] = 1 ;
        for(int i = 2 ; i <= n ; i ++) {
            if(!notp[i]) {
                p[++pnum] = i ;
                sum[i] = ((i - 1LL * i * i % mod) % mod + mod) % mod ;
            }
            for(int j = 1 ; j <= pnum && 1LL * i * p[j] <= n ; j ++) {
                notp[i * p[j]] = true ;
                if(i % p[j] == 0) {
                    sum[i * p[j]] = (1LL * sum[i] * p[j] % mod + mod) % mod ;
                    break ;
                }
                sum[i * p[j]] = (1LL * sum[i] * sum[p[j]] % mod + mod) % mod ;
            }
        }
        for(int i = 1 ; i <= n ; i ++) {
            sum[i] = ((sum[i - 1] + sum[i]) % mod + mod) % mod ;
            f[i] = (f[i - 1] + i) % mod ;
        }
    }
    int main() {
        int T = read() ; Get_Sum(10000000) ;
        while(T --) {
            n = read() ; m = read() ; if(n > m) swap(n , m) ; Ans = 0 ;
            for(int l = 1 , r ; l <= n ; l = r + 1) {
                r = min(n / (n / l) , m / (m / l)) ;
                Ans = (Ans + 1LL * f[n / l] * f[m / l] % mod * (sum[r] - sum[l - 1] + mod) % mod + mod) % mod ;
            }
            printf("%d
    ",(Ans % mod + mod) % mod) ;
        }
        return 0 ;
    }
    
  • 相关阅读:
    《天才在左,疯子在右》
    MVC思想概述
    java文件读写
    HTTP协议简单笔记
    自学Python_Day01
    Linux基础介绍篇
    PHP学习 Day_01
    Linux中部分命令英语全拼
    Linux学习基础命令(三)
    Linux学习基础命令(二)
  • 原文地址:https://www.cnblogs.com/beretty/p/10372047.html
Copyright © 2011-2022 走看看