zoukankan      html  css  js  c++  java
  • [51 Nod 1584] 加权约数和

    题意


    求$$large sum_{i=1}^Nsum_{j=1}^Nmax(i,j)cdotsigma_1(ij)$$
    其中
    $1le Nle10^6$
    $1le Tle5cdot10^4$
    $sigma_1(n)$表示$n$的约数和
    ### 题目分析
    令$A=sum_{i=1}^nsum_{j=1}^iicdotsigma_1(ij),B=sum_{i=1}^nicdotsigma_1(i^2)$,则$Ans=2A-B$

    且有
    $$large
    egin{aligned}
    A&=sum_{i=1}^nicdotsum_{j=1}^isum_{x|i}sum_{y|j}xcdot j/y[(x,y)=1]\
    &=sum_{i=1}^nicdotsum_{j=1}^isum_{x|i}sum_{y|j}xcdot j/ysum_{d|(x,y)}mu(d)\
    &=sum_{d=1}^nmu(d)sum_{d|x}xsum_{x|i}isum_{d|y}sum_{y|j}^ifrac jy\
    &=sum_{d=1}^nmu(d)sum_{x=1}^{lfloorfrac nd floor}dxsum_{x|i}^{lfloorfrac nd floor}disum_{y=1}^{lfloorfrac nd floor}sum_{y|j}^ifrac{dj}{dy}\
    &=sum_{d=1}^nmu(d)d^2sum_{i=1}^{lfloorfrac nd floor}isum_{x|i}xsum_{y=1}^{lfloorfrac nd floor}sum_{y|j}^iy\
    &=sum_{d=1}^nmu(d)d^2sum_{i=1}^{lfloorfrac nd floor}icdotsigma_1(i)sum_{j=1}^{i}sigma_1(j)\
    &=sum_{d=1}^nmu(d)d^2sum_{i=1}^{lfloorfrac nd floor}icdotsigma_1(i)cdot S_{sigma_1}(i)\end{aligned}$$
    $$large
    egin{aligned}
    B&=sum_{i=1}^nisum_{x|i}sum_{y|i}xcdot i/y[(x,y)=1]\
    &=sum_{i=1}^nicdotsum_{x|i}sum_{y|i}xcdot i/ysum_{d|(x,y)}mu(d)\
    &=sum_{d=1}^nmu(d)sum_{d|i}isum_{d|x|i}sum_{d|y|i}xcdot frac iy\
    &=sum_{d=1}^nmu(d)sum_{i=1}^{lfloorfrac nd floor}disum_{x|i}sum_{y|i}dxcdot frac {di}{dy}\
    &=sum_{d=1}^nmu(d)d^2sum_{i=1}^{lfloorfrac nd floor}isum_{x|i}xsum_{y|i}frac {i}{y}\
    &=sum_{d=1}^nmu(d)d^2sum_{i=1}^{lfloorfrac nd floor}isum_{x|i}xsum_{y|i}y\
    &=sum_{d=1}^nmu(d)d^2sum_{i=1}^{lfloorfrac nd floor}icdotsigma_1(i)^2\
    end{aligned}$$
    $$large
    egin{aligned}
    herefore Ans(n)&=2A-B\&=sum_{d=1}^nmu(d)d^2sum_{i=1}^{lfloorfrac nd floor}icdotsigma_1(i)(2cdot S_{sigma_1}(i)-sigma_1(i))
    end{aligned}$$

    发现$Ans(n)$可以递推:
    $$Ans(n)=Ans(n-1)+sum_{d|n}mu(d)d^2{lfloorfrac nd floor}cdotsigma_1({lfloorfrac nd floor})(2cdot S_{sigma_1}({lfloorfrac nd floor})-sigma_1({lfloorfrac nd floor}))$$
    那么就可以$O(nlog n)$预处理了。

    然后每次$O(1)$回答就完了。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 1000005;
    const int mod = 1000000007;
    int Cnt, Prime[N], mu[N];
    LL ans[N], sd[N], a[N], d[N], f[N];
    bool IsnotPrime[N];
    
    void init() {
    	d[1] = 1, a[1] = 1, mu[1] = 1;
    	for(int i = 2; i < N; ++i) {
    		if(!IsnotPrime[i])
    			Prime[++Cnt] = i, d[i] = a[i] = 1+i, mu[i] = -1;
    		for(int j = 1, k; j <= Cnt && i * Prime[j] < N; ++j) {
    			IsnotPrime[k = i * Prime[j]] = 1;
    			if(i % Prime[j] == 0) {
    				mu[k] = 0;
    				a[k] = a[i] * Prime[j] + 1;
    				d[k] = d[i] / a[i] * a[k];
    				break;
    			}
    			mu[k] = -mu[i];
    			a[k] = 1 + Prime[j];
    			d[k] = d[i] * a[k];
    		}
    	}
    	for(int i = 1; i < N; ++i) {
    		sd[i] = (sd[i-1] + (d[i]%=mod)) % mod;
    		f[i] = i*d[i]%mod*(2*sd[i]-d[i]+mod)%mod;
    	}
    	for(int i = 1; i < N; ++i) if(mu[i])
    		for(int j = i; j < N; j += i)
    			ans[j] = (ans[j] + 1ll*mu[i]*i*i%mod*f[j/i]%mod + mod) % mod;
    	for(int i = 1; i < N; ++i) ans[i] = (ans[i-1] + ans[i]) % mod;
    }
    int main () {
    	init();
    	int T, ks = 0, N; scanf("%d", &T);
    	while(T--) scanf("%d", &N), printf("Case #%d: %lld
    ", ++ks, ans[N]);
    }
    

      

  • 相关阅读:
    1.2 C++命名空间(namespace)
    1.3 C++引用(Reference)
    在ros功能包CMakeLists.txt中获取所在功能包的路径 便于添加第三方库的相对路径
    ubuntu14.04下搜狗输入法不能输入中文问题解决
    js对日期的判断
    Calendar用法随笔
    键盘事件
    onkeyup+onafterpaste 只能输入数字和小数点--转载
    导出数据到EXL表格中
    DENON AVR-X510BT 功放设置记录
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039450.html
Copyright © 2011-2022 走看看