zoukankan      html  css  js  c++  java
  • Solution -「洛谷 P3911」最小公倍数之和

    (mathcal{Description})

      Link.

      给定 ({a_n}),求:

    [sum_{i=1}^nsum_{j=1}^noperatorname{lcm}(a_i,a_j) ]

      (1le n,a_ile5 imes10^4)

    (mathcal{Solution})

      数论题在序列上搞不太现实,记最大值 (m),有 (c_i)(a_j=i),推式子:

    [egin{aligned} sum_{i=1}^nsum_{j=1}^noperatorname{lcm}(a_i,a_j)&=sum_{i=1}^msum_{j=1}^mfrac{ij}{gcd(i,j)}c_ic_j\ &=sum_{d=1}^msum_{i=1}^{lfloorfrac{m}d floor}sum_{j=1}^{lfloorfrac{m}d floor}[gcd(i,j)=1]dijc_ic_j\ &=sum_{d=1}^msum_{i=1}^{lfloorfrac{m}d floor}sum_{j=1}^{lfloorfrac{m}d floor}dijc_ic_jsum_{D|iland D|j}mu(D)~~~~( ext{Mobius 反演})\ &=sum_{d=1}^mdsum_{D=1}^{lfloorfrac{m}d floor}mu(D)D^2sum_{i=1}^{lfloorfrac{m}{dD} floor}sum_{j=1}^{lfloorfrac{m}{dD} floor}ijc_{idD}c_{jdD}~~~~( ext{交换枚举顺序})\ &=sum_{T=1}^mTsum_{D|T}mu(D)Dsum_{i=1}^{lfloorfrac{m}T floor}sum_{j=1}^{lfloorfrac{m}T floor}ijc_{iT}c_{jT}~~~~( ext{改换枚举}~T=dD)\ &=sum_{T=1}^mTleft(sum_{i=1}^{lfloorfrac{m}T floor}ic_{iT} ight)^2sum_{D|T}mu(D)D end{aligned} ]

      (mathcal O(n+msqrt m)) 算就好啦。

    (mathcal{Code})

    #include <cmath>
    #include <cstdio>
    
    const int MAXN = 5e4;
    int n, m, c[MAXN + 5];
    int pn, pr[MAXN + 5], mu[MAXN + 5];
    bool vis[MAXN + 5];
    
    inline int rint () {
    	int x = 0; char s = getchar ();
    	for ( ; s < '0' || '9' < s; s = getchar () );
    	for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
    	return x;
    }
    
    inline void sieve ( const int n ) {
    	mu[1] = 1;
    	for ( int i = 2; i <= n; ++ i ) {
    		if ( !vis[i] ) mu[pr[++ pn] = i] = -1;
    		for ( int j = 1, t; j <= pn && ( t = i * pr[j] ) <= n; ++ j ) {
    			vis[t] = true;
    			if ( !( i % pr[j] ) ) break;
    			mu[t] = -mu[i];
    		}
    	}
    }
    
    int main () {
    	n = rint ();
    	for ( int i = 1, a; i <= n; ++ i ) {
    		++ c[a = rint ()];
    		if ( m < a ) m = a;
    	}
    	sieve ( m );
    	long long ans = 0;
    	for ( int i = 1; i <= m; ++ i ) {
    		long long a = 0, b = 0;
    		for ( int j = 1, t = m / i; j <= t; ++ j ) a += 1ll * j * c[i * j];
    		for ( int j = 1, t = sqrt ( i ); j <= t; ++ j ) {
    			if ( i % j ) continue;
    			b += mu[j] * j;
    			if ( j * j < i ) b += mu[i / j] * i / j;
    		}
    		ans += 1ll * i * a * a * b;
    	}
    	printf ( "%lld
    ", ans );
    	return 0;
    }
    

    (mathcal{Details})

      推的时候把 (ij) 系数搞丢了自闭半天 qaq。

  • 相关阅读:
    Kali渗透测试工具-netcat
    信息收集工具-dimtry
    Beef xss神器
    Scapy编写ICMP扫描脚本
    全国职业技能大赛信息安全管理与评估-MySQL弱口令利用
    crawler 听课笔记 碎碎念 2 一些爬虫须知的基本常识和流程
    crawler 听课笔记 碎碎念 3 关于python的细枝末节的回顾复习
    关于互信息(Mutual Information),我有些话要说
    最让人头疼的清洗数据过程----选择合适的方式快速命中所需的数据
    利用小虫虫做一枚合格宅男,果然牡丹花下做鬼也风流
  • 原文地址:https://www.cnblogs.com/rainybunny/p/13638952.html
Copyright © 2011-2022 走看看