zoukankan      html  css  js  c++  java
  • 某考试 T1 function

    (数据范围 n<=10^9 ,T<=10 )

    首先,我来证明一下 Σμ(d) * σ(i/d)^2 = σ(i^2)  

    相信做过约数个数和的童鞋都可以完成从右式推到左式,那么我现在就说一下怎么从左边推到右边。

         Σμ(d) * σ(i/d)^2

    = Σμ(d) * Σ(d|p|i) * Σ(d|q|i)

    = Σ(p|i) * Σ(q|i) * Σ(d|p,d|q) μ(d)

    = Σ(p|i) * Σ(q|i) * [gcd(p,q)==1]

    = σ(i^2)

    然后这个题就变成了昨天晚上我做的那个题。

    但是我突然又想再推一遍式子。。。

        σ(i^2) 

    = (2*a1 + 1)(2*a2 + 1)(2*a3 + 1)...(2*ak + 1)

    = Σ(S属于{1,2,...k}) 2^|S|  *  π(i属于S) ai

    = Σ (p|i) 2^w(p)

    其中w(x)表示x的质因子个数。

    又因为 2^w(x) = Σ (d|x) μ(d)^2

    所以上式的前缀和就可以转化成μ^2和σ的前缀和之间的运算了

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1000000;
    int zs[maxn/5],t=0,T,sq[maxn+5];
    int miu[maxn+5],low[maxn+5],n;
    bool v[maxn+5];
    ll d[maxn+5];
    
    inline void init(){
    	miu[1]=1,d[1]=1,low[1]=1;
    	for(int i=2;i<=maxn;i++){
    		if(!v[i]) zs[++t]=i,miu[i]=-1,d[i]=2,low[i]=i;
    		for(int j=1,u;j<=t&&(u=zs[j]*i)<=maxn;j++){
    			v[u]=1;
    			if(!(i%zs[j])){
    				low[u]=low[i]*zs[j];
    				if(low[i]==i) d[u]=d[i]+1;
    				else d[u]=d[low[u]]*d[i/low[i]];
    				break;
    			}
    			
    			low[u]=zs[j];
    			d[u]=d[i]<<1;
    			miu[u]=-miu[i];
    		}
    	}
    	
    	for(int i=1;i<=maxn;i++) d[i]+=d[i-1];
    	for(int i=1;i<=maxn;i++) sq[i]=sq[i-1]+miu[i]*miu[i];
    }
    
    inline int getsq(int x){
    	if(x<=maxn) return sq[x];
    	
    	ll an=0;
    	for(int i=1;i*(ll)i<=x;i++){
    		an+=miu[i]*(x/(i*(ll)i));
    	}
    	return an;
    }
    
    inline ll getd(int x){
    	if(x<=maxn) return d[x];
    	
    	ll an=0;
    	for(int i=1,j,now;i<=x;i=j+1){
    		now=x/i,j=x/now;
    		an+=(j-i+1)*(ll)now;
    	}
    	return an;
    }
    
    inline ll query(int x){
    	ll an=0;
    	for(int i=1,j,now;i<=x;i=j+1){
    		now=x/i,j=x/now;
    		an+=(getsq(j)-getsq(i-1))*getd(now);
    	}
    	return an;
    }
    
    int main(){
    	freopen("function.in","r",stdin);
    	freopen("function.out","w",stdout);
    	
    	scanf("%d",&T);
    	init();
    	while(T--){
    		scanf("%d",&n);
    		printf("%lld
    ",query(n));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    matplotlib讲义
    车间调度问题(part3: 遗传算法)
    sympy库和matplotlib库简介
    python列表
    第十周周三练习
    第十一周周一练习题
    MyEcplise中关于部署文件不成功的问题
    Java中的get()和set()方法
    Java中this关键字的使用
    信号完整性问题的几个基本原则
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8512396.html
Copyright © 2011-2022 走看看