• 题解 LOJ 6053


    传送门


    【分析】

    显然 (oldsymbol f) 为积性函数,且 (oldsymbol f(p)=poplus 1=oldsymbol varphi(p)cdot 3^{[2mid p]})

    (oldsymbol g(p)=oldsymbol varphi(p)cdot 3^{[2mid p]})(oldsymbol f=oldsymbol g*oldsymbol h) ,则:

    (egin{aligned} oldsymbol f(p^k)&=sum_{i=0}^koldsymbol h(p^i)oldsymbol g(p^{k-i}) \\ oldsymbol f(p^k)&=sum_{i=1}^{k-1}oldsymbol h(p^i)oldsymbol g(p^{k-i})+oldsymbol h(p^k)+oldsymbol g(p^k) \\ oldsymbol h(p^k)&=oldsymbol f(p^k)-oldsymbol g(p^k)-sum_{i=1}^{k-1}oldsymbol h(p^i)oldsymbol g(p^{k-i}) end{aligned})

    (p>2) 时:

    (egin{aligned} oldsymbol h(p^k)&=(poplus k)-p^{k-1}(p-1)-sum_{i=1}^{k-1}oldsymbol h(p^i)cdot p^{k-i-1}cdot (p-1) \\oldsymbol h(p^{k-1})&=(poplus k-1)-p^{k-2}(p-1)-sum_{i=1}^{k-2}oldsymbol h(p^i)cdot p^{k-i-2}cdot (p-1) \\oldsymbol h(p^k)-poldsymbol h(p^{k-1})&=(poplus k)-p(poplus k-1)-oldsymbol h(p^{k-1})cdot (p-1) \\oldsymbol h(p^k)&=oldsymbol h(p^{k-1})+(poplus k)-p(poplus k-1) end{aligned})

    (p=2) 时:

    (egin{aligned} oldsymbol h(p^k)&=(poplus k)-3p^{k-1}(p-1)-sum_{i=1}^{k-1}oldsymbol h(p^i)cdot 3p^{k-i-1}cdot (p-1) \\oldsymbol h(p^{k-1})&=(poplus k-1)-3p^{k-2}(p-1)-sum_{i=1}^{k-2}oldsymbol h(p^i)cdot 3p^{k-i-2}cdot (p-1) \\oldsymbol h(p^k)-poldsymbol h(p^{k-1})&=(poplus k)-p(poplus k-1)-oldsymbol h(p^{k-1})cdot 3(p-1) \\oldsymbol h(2^k)-2oldsymbol h(2^{k-1})&=(2oplus k)-2(2oplus k-1)-3oldsymbol h(2^{k-1}) \\oldsymbol h(2^k)&=-oldsymbol h(2^{k-1})+(2oplus k)-2(2oplus k-1) end{aligned})

    而由于 (oldsymbol varphi(p)cdot 3^{[2mid p]}=oldsymbol f(p)=oldsymbol h(p)+oldsymbol g(p)=oldsymbol h(p)+oldsymbol varphi(p)cdot 3^{[2mid p]}) 得到 (oldsymbol h(p)=0)

    从而根据上述式子 (k>1) 时,(oldsymbol h(p^k)) 可以由 (oldsymbol h(p^{k-1})) 递推得到


    我们定义 Powerful Number 为所有质因子均出现大于 (1) 次的数,以集合语言来讲,则是 (PN={n|forall (p_imid n) o (p_i^2mid n), p_iin Prime})

    则不难发现,(oldsymbol h(n)=0, n otin PN) 且所有 Powerful Number 均可写为 (a^2b^3(a, bin Z_+)) 的形式

    (n) 范围内,Powerful Number 的数量级为 (displaystyle sum_{a=1}^{sqrt n} sum_{b=1}^{sqrt[3] {nover a^2}}1=int_1^{sqrt n} ext daint_1^{sqrt[3]{nover a^2}} ext db=O(sqrt n))

    (egin{aligned} sum_{i=1}^noldsymbol f(i)&=sum_{i=1}^nsum_{dmid i}oldsymbol h(d)cdot oldsymbol g({iover d}) \\&=sum_{d=1}^noldsymbol h(d)cdot sum_{i=1}^{n/d}oldsymbol g(i) \\&=sum_{d in PN}oldsymbol h(d)cdot G(n/d)&& ext{(}oldsymbol h ext{ 仅在 }PN ext{ 处有值 } ext{)} end{aligned})

    只要预处理 (sqrt n) 范围内的质数,然后跑 dfs 即可在 (O(sqrt n)) 时间内枚举所有 Powerful Number


    先问题化为对于 (G(n)) 如何求解

    (egin{aligned} G(n)&=sum_{i=1}^n3^{[2mid i]}oldsymbol varphi(i) \\&=sum_{i=1}^n oldsymbol varphi(i)+2sum_{i=1}^n[2mid i]oldsymbol varphi(i) \\&=Phi(n)+2sum_{i=1}^{n/2}oldsymbol varphi(2i) \\&=Phi(n)+2S(n/2) \\ \\S(n)&=sum_{i=1}^n oldsymbol varphi(2i) \\&=sum_{i=1}^n oldsymbol varphi(i)+sum_{i=1}^n[2mid i]oldsymbol (i) \\&=Phi(n)+S(n/2) \\&=Phi(n)+Phi(n/2)+Phi(n/4)+Phi(n/8)+cdots&& ext{(}迭代 ext{)} \\ \\G(n)&=Phi(n)+2[Phi(n/2)+Phi(n/4)+Phi(n/8)+cdots] \\&=2[Phi(n)+Phi(n/2)+Phi(n/4)+Phi(n/8)+cdots]-Phi(n) end{aligned})

    (oldsymbol varphi*oldsymbol I=oldsymbol {id}) 得:

    (displaystyle {n(n+1)over 2}=sum_{i=1}^noldsymbol {id}(i)=sum_{i=1}^nsum_{dmid i}oldsymbol varphi({iover d})=sum_{d=1}^nPhi(n/d))

    变型得到 (displaystyle Phi(n)={n(n+1)over 2}-sum_{d=2}^nPhi(n/d)) ,可由杜教筛在 (O(n^{2over 3})) 时间内预处理得到


    总时间复杂度为杜教筛的预处理时间 (O(n^{2over 3})+) 杜教筛的运行时间 (O(n^{2over 3})+) 迭代 (G(n)) 的时间 (O(sqrt nlog n)+) PN 筛的时间 (O(sqrt n))

    总复杂度为 (O(n^{2over 3}+sqrt nlog n))


    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll, ll> pii;
    typedef double db;
    #define fi first
    #define se second
    const int Lim=5e6, MAXN=Lim+10, P=1e9+7;
    int fc[MAXN], prime[MAXN/10], cntprime, sphi[MAXN];
    inline void sieve() {
    	for(int i=2; i<=Lim; ++i) {
    		if(!fc[i]) {
    			prime[++cntprime]=i;
    			fc[i]=i;
    			sphi[i]=i-1;
    		}
    		for(int j=1; j<=cntprime; ++j)
    			if(prime[j]*i>Lim) break;
    			else if(prime[j]<fc[i]) {
    				fc[prime[j]*i]=prime[j];
    				sphi[ prime[j]*i ]=sphi[ prime[j] ]*sphi[i];
    			}
    			else{
    				fc[prime[j]*i]=prime[j];
    				sphi[ prime[j]*i ]=prime[j]*sphi[i];
    				break;
    			}
    	}
    	sphi[1]=1;
    	for(int i=2; i<=Lim; ++i) {
    		sphi[i]+=sphi[i-1];
    		if(sphi[i]>=P) sphi[i]-=P;
    	}
    }
    struct Dusieve{
    	ll n, val[MAXN];
    	int Sphi[MAXN], G[MAXN];
    	int sqr, id1[MAXN], id2[MAXN], cntid;
    	inline int getid(ll val) { return val<=sqr?id1[val]:id2[n/val]; }
    	inline int query(ll n) { return G[getid(n)]; }
    	inline void init(ll n_) {
    		n=n_;
    		cntid=0;
    		sqr=sqrt(n)+0.5;
    		for(ll l=1, r, d; l<=n; l=r+1) {
    			r=n/(val[++cntid]=d=n/l);
    			if(d>sqr) id2[n/d]=cntid;
    			else id1[d]=cntid;
    		}
    	}
    	inline void work() {
    		for(int i=cntid; i>=1; --i) {
    			if(val[i]<=Lim) {
    				Sphi[i]=sphi[ val[i] ];
    				continue;
    			}
    			ll v=val[i];
    			int &res=Sphi[i];
    			res=(v%P); res=(ll)res*(res+1)%P*(P+1>>1)%P;
    			for(ll l=2, r, d; l<=v; l=r+1) {
    				r=v/(d=v/l);
    				res-=(r-l+1)*Sphi[getid(d)]%P;
    				if(res<0) res+=P;
    			}
    		}
    
    		for(int i=cntid; i>=1; --i) {
    			int &res=G[i];
    			ll v=val[i];
    			while(v) {
    				res+=Sphi[getid(v)];
    				if(res>=P) res-=P;
    				v>>=1;
    			}
    			res=(res*2%P-Sphi[i]+P)%P;
    		}
    	}
    }ds;
    
    inline int ans(ll n, int flr, int hn) {
    	int res=(ll)hn*ds.query(n)%P;
    	for(int i=flr+1; i<=cntprime; ++i) {
    		int p=prime[i], k=1;
    		ll val=n/p, newhn=0;
    		if(val<p) break;
    		while(val>=p) {
    			val/=p; ++k;
    			if(p==2) newhn=(-newhn+(k^2)-2*(k-1^2));
    			else newhn=newhn+(p^k)-(ll)p*(p^k-1);
    			newhn=((newhn%=P)<0?newhn+P:newhn);
    			res+=ans(val, i, (ll)hn*newhn%P);
    			if(res>=P) res-=P;
    		}
    	}
    	return res;
    }
    
    ll n;
    int main(){
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
    	sieve();
    	cin>>n;
    	ds.init(n);
    	ds.work();
    	cout<<ans(n, 0, 1);
        cout.flush();
        return 0;
    }
    
  • 相关阅读:
    vue+axios实现文件下载
    处理 Vue 单页面应用 SEO
    JSON.parse()与JSON.stringify()的区别
    JS设置Cookie过期时间
    <div>标签仿<textarea>。contentEditable=‘true’,赋予非表单标签内容可以编辑
    CSS上下左右居中的几种方法
    jqGrid 修改单元格值或者替换图片及其他
    对于Web性能优化, 了解和经验
    初步了解反射案列
    JS IndexOf移除符合规则的一项
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/15356768.html
Copyright © 2020-2023  润新知