zoukankan      html  css  js  c++  java
  • loj #6179. Pyh 的求和 莫比乌斯反演

    题目描述

    传送门

    (sumlimits_{i=1}^nsumlimits_{j=1}^m varphi(ij)(mod 998244353))

    (T) 组询问

    (1 leq n,m,T leq 10^5)

    分析

    (n<m)

    首先,我们把 (varphi(ij)) 拆成 (varphi(i)varphi(j)frac{gcd(i,j)}{varphi(gcd(i,j))})

    考虑求单个欧拉函数的方法

    (varphi(i)=iprodlimits_{d in prime,d|i}frac{d-1}{d})

    (varphi(i)varphi(j))(varphi(ij)) 多乘了 (i,j) 共有的质因子

    所以我们要把这些共有的质因子做出的贡献消除

    即乘上一个 (frac{gcd(i,j)}{varphi(gcd(i,j))})

    那么式子就变成了

    (sumlimits_{i=1}^nsumlimits_{j=1}^mvarphi(i)varphi(j)frac{gcd(i,j)}{varphi(gcd(i,j))})

    按照莫比乌斯反演的套路,枚举 (gcd(i,j))

    (sumlimits_{d=1}^nfrac{d}{varphi(d)}sumlimits_{i=1}^{n/d}sumlimits_{j=1}^{m/d}varphi(id)varphi(jd)[gcd(i,j)=1])

    (sumlimits_{d=1}^nfrac{d}{varphi(d)}sumlimits_{i=1}^{n/d}sumlimits_{j=1}^{m/d}varphi(id)varphi(jd)sumlimits_{k|gcd(i,j)}mu(k))

    (sumlimits_{d=1}^nfrac{d}{varphi(d)}sumlimits_{k=1}^{n/d}mu(k)sumlimits_{i=1}^{n/dk}sumlimits_{j=1}^{m/dk}varphi(idk)varphi(jdk))

    (sumlimits_{T=1}^nsumlimits_{d|T}frac{d}{varphi(d) }mu(frac{T}{d})sumlimits_{i=1}^{n/T}sumlimits_{j=1}^{m/T}varphi(iT)varphi(jT))

    (g(T)=sumlimits_{d|T}frac{d}{varphi(d) }mu(frac{T}{d}),s(n,m)=sumlimits_{i=1}^nvarphi(mi))

    原式变成

    (sumlimits_{T=1}^ng(T)s(n/T,T)s(m/T,T))

    (g) 数组和 (s) 数组可以 (nlogn) 预处理出来

    然后就可以 (O(n)) 计算每一次的答案

    总复杂度就是 (O(nT)),还是不够优秀

    我们可以人为地设一个值 (top)

    (T<frac{m}{top}) 时暴力计算

    否则 (frac{n}{T},frac{m}{T}) 一定是小于 (top)

    那么我们就可以开一个数组把小于 (top) 的这一部分预处理出来

    查询的时候就可以直接用

    这道题的内存限制是 (64M)

    所以不能直接开数组

    而要开一个内存池或者用 (vector)

    代码

    #include<cstdio>
    #include<cmath>
    #include<vector>
    #define rg register
    const int maxn=1e5+5,maxm=55,mod=998244353,tp=52;
    inline int addmod(rg int now1,rg int now2){
    	return now1+=now2,now1>=mod?now1-mod:now1;
    }
    inline int delmod(rg int now1,rg int now2){
    	return now1-=now2,now1<0?now1+mod:now1;
    }
    inline int mulmod(rg long long now1,rg int now2){
    	return now1*=now2,now1>=mod?now1%mod:now1;
    }
    int pri[maxn],mmax,phi[maxn],mu[maxn],g[maxn],*f[maxm][maxm],buf[maxn*160],*o=buf,*s[maxn];
    int ksm(rg int ds,rg int zs){
    	rg int nans=1;
    	while(zs){
    		if(zs&1) nans=mulmod(nans,ds);
    		ds=mulmod(ds,ds);
    		zs>>=1;
    	}
    	return nans;
    }
    bool not_pri[maxn];
    void pre(){
    	not_pri[0]=not_pri[1]=1;
    	phi[1]=mu[1]=1;
    	for(rg int i=2;i<=mmax;i++){
    		if(!not_pri[i]){
    			pri[++pri[0]]=i;
    			phi[i]=i-1;
    			mu[i]=mod-1;
    		}
    		for(rg int j=1;j<=pri[0] && 1LL*i*pri[j]<=mmax;j++){
    			not_pri[i*pri[j]]=1;
    			if(i%pri[j]==0){
    				phi[i*pri[j]]=mulmod(pri[j],phi[i]);
    				break;
    			} else {
    				phi[i*pri[j]]=mulmod(phi[pri[j]],phi[i]);
    				mu[i*pri[j]]=mulmod(mu[pri[j]],mu[i]);
    			}
    		}
    	}
    	rg int cs;
    	for(rg int i=1;i<=mmax;i++){
    		cs=mulmod(i,ksm(phi[i],mod-2));
    		for(rg int j=i,now=1;j<=mmax;j+=i,now++){
    			g[j]=addmod(g[j],mulmod(cs,mu[now]));
    		}
    	}
    	for(rg int i=1;i<=mmax;i++){
    		cs=mmax/i;
    		s[i]=o;
    		o+=(cs+1);
    		for(rg int j=1;j<=cs;j++){
    			s[i][j]=addmod(s[i][j-1],phi[i*j]);
    		}
    	}
    	for(rg int i=1;i<=tp;i++){
    		for(rg int j=1;j<=tp;j++){
    			f[i][j]=o;
    			f[i][j][0]=0;
    			cs=std::min(mmax/i,mmax/j);
    			o+=(cs+1);
    			for(rg int k=1;k<=cs;k++){
    				f[i][j][k]=(addmod(f[i][j][k-1],mulmod(g[k],mulmod(s[k][i],s[k][j]))));
    			}
    		}
    	}
    }
    int t,n,m;
    int main(){
    	mmax=1e5;
    	pre();
    	scanf("%d",&t);
    	while(t--){
    		scanf("%d%d",&n,&m);
    		if(n>m) std::swap(n,m);
    		rg int nans=0,mmax=m/tp,orz1,orz2;
    		for(rg int i=1;i<=mmax;i++){
    			nans=addmod(nans,mulmod(g[i],mulmod(s[i][n/i],s[i][m/i])));
    		}
    		for(rg int l=mmax+1,r;l<=n;l=r+1){
    			r=std::min((n/(n/l)),m/(m/l)),orz1=n/l,orz2=m/l;
    			nans=addmod(nans,delmod(f[orz1][orz2][r],f[orz1][orz2][l-1]));
    		}
    		printf("%d
    ",nans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    606. Construct String from Binary Tree
    696. Count Binary Substrings
    POJ 3255 Roadblocks (次短路)
    POJ 2823 Sliding Window (单调队列)
    POJ 1704 Georgia and Bob (博弈)
    UVa 1663 Purifying Machine (二分匹配)
    UVa 10801 Lift Hopping (Dijkstra)
    POJ 3281 Dining (网络流之最大流)
    UVa 11100 The Trip, 2007 (题意+贪心)
    UVaLive 4254 Processor (二分+优先队列)
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/14261292.html
Copyright © 2011-2022 走看看