• P3312 数表


    P3312 数表

    题意

    求出

    [sum_{i=1}^nsum_{j=1}^msigma(gcd(i,j))[sigma(gcd(i,j))le a] ]

    其中 (sigma) 表示约数和。

    思路/推导

    考虑没有 (a) 的限制的情况。

    [egin{aligned} ans&=sum_{d=1}^{min(n,m)}sigma(d)sum_{i=1}^{leftlfloorfrac{n}{d} ight floor}sum_{j=1}^{leftlfloorfrac{m}{d} ight floor}[gcd(i,j)=1]\ &=sum_{d=1}^{min(n,m)}sigma(d)sum_{i=1}^{leftlfloorfrac{n}{d} ight floor}sum_{j=1}^{leftlfloorfrac{m}{d} ight floor}sum_{pmid iland pmid j}mu(p)\ &=sum_{d=1}^{min(n,m)}sigma(d)sum_{p=1}^{leftlfloorfrac{min(n,m)}{d} ight floor}mu(p)leftlfloorfrac{n}{dp} ight floorleftlfloorfrac{m}{dp} ight floor\ &=sum_{T=1}^{min(n,m)}sum_{d=1}^Tsigma(d)mu(frac Td)leftlfloorfrac{n}{T} ight floorleftlfloorfrac{m}{T} ight floor end{aligned} ]

    考虑加入 (a) 的限制。将询问按照 (a) 大小离线,然后用一个树状数组维护 (sum_dsigma(d)mu(frac Td)) 的前缀和即可。

    具体是将线性筛出的所有数的约数和从小到大进行排序,在从小到大查询的时候进行更新。

    不会筛 (sigma) 的可以看我的另一篇博客

    时间复杂度瓶颈在于查询,需要用到数论分块,为 (O(qsqrt nlog n))

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #include<cstring>
    #include<cmath>
    #include<utility>
    using namespace std;
    inline int read(){
    	int w=0,x=0;char c=getchar();
    	while(!isdigit(c))w|=c=='-',c=getchar();
    	while(isdigit(c))x=x*10+(c^48),c=getchar();
    	return w?-x:x;
    }
    namespace star
    {
    	const int maxn=1e5+10,maxm=2e4+10,N=1e5;
    	int n,p[maxn/10],mu[maxn],tot,c[maxn],ans[maxm],g[maxn];
    	pair<int,int> f[maxn];
    	bool mark[maxn];
    	inline void insert(int x,int k){for(;x<=N;x+=x&-x) c[x]+=k;}
    	inline int query(int x){int ans=0;for(;x;x-=x&-x) ans+=c[x];return ans;}
    	struct Query{
    		int n,m,a,id;
    		inline bool operator < (const Query& zp) const {return a<zp.a;}
    		inline int solve(){
    			if(n>m) swap(n,m);
    			int ans=0;
    			for(int l=1,r;l<=n;l=r+1)
    				r=min(n/(n/l),m/(m/l)),ans+=((query(r)-query(l-1))*(n/l)*(m/l));
    			return ans;
    		}
    	}q[maxm];
    	inline void work(){
    		mu[1]=1;
    		f[1]=make_pair(1,1);
    		for(int i=2;i<=N;i++){
    			if(!mark[i]) p[++tot]=i,mu[i]=-1,g[i]=i+1,f[i]=make_pair(i+1,i);
    			for(int j=1,tmp;j<=tot and (tmp=i*p[j])<=N;j++){
    				mark[tmp]=true;
    				if(i%p[j]==0){
    					mu[tmp]=0;
    					g[tmp]=g[i]*p[j]+1;
    					f[tmp]=make_pair(f[i].first/g[i]*g[tmp],tmp);
    					break;
    				}
    				mu[tmp]=-mu[i];
    				g[tmp]=p[j]+1;
    				f[tmp]=make_pair(f[i].first*f[p[j]].first,tmp);
    			}
    		}
    		sort(f+1,f+1+N);
    		n=read();
    		for(int i=1;i<=n;i++) q[i].n=read(),q[i].m=read(),q[i].a=read(),q[i].id=i;
    		sort(q+1,q+1+n);
    		for(int i=1,j=1;i<=n;i++){
    			while(f[j].first<=q[i].a and j<=N){
    				for(int k=f[j].second;k<=N;k+=f[j].second) insert(k,f[j].first*mu[k/f[j].second]);
    				j++;
    			}
    			ans[q[i].id]=q[i].solve();
    		}
    		for(int i=1;i<=n;i++) printf("%d
    ",ans[i]&(~(1<<31)));
    	}
    }
    signed main(){
    	star::work();
    	return 0;
    }
    
  • 相关阅读:
    找不到 .NETFramework,Version=v5.0 的引用程序集。要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序。
    从pfx私钥证书中提取私钥
    更改域密码
    realtek高清晰音频管理器 WIN10
    LINQ to Entities does not recognize the method 'System.String ToString()' method
    C# ML.NET 使用GPU遇到 Failed to get convolution algorithm.This is probably because cuDNN failed to initialize
    8款开源自动化测试框架
    质量管理大师:戴明、克劳士比、朱兰、菲根堡姆
    接口测试数据建模
    稻盛和夫:一场高效的会议,一定是让员工多说
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/14360173.html
Copyright © 2020-2023  润新知