zoukankan      html  css  js  c++  java
  • TopCoder

    TopCoder - 12584 SRM 582 Div 1 SemiPerfectPower (莫比乌斯反演)

    题目大意:

    给定(L,R),求([L,R])中能够表示为(acdot b^c(1leq a<b,c>1))的数(SemiPerfect数)的个数

    (Rleq 8cdot 10^{16})

    解题思路

    首先显然可以通过作差转化为求([1,n])内的个数

    接下来考虑简化(c)的情形

    推论:任何一个SemiPerfect数可以表示为(cleq 3)的形式

    证明:若(c>3),对于(n=acdot b^c(c>3))

    (2|c)时,显然存在形如(n=acdot (b^{frac{c}{2}})^{2})的表示

    (2 ot |c)时,可以表示为(n=(acdot c)cdot (b^{frac{c-1}{2}})^2)同样合法

    接下来考虑对于两种情况分类讨论

    为了便于叙述,令(F(n)=max lbrace kin N^+| k^2|n brace)

    (G(n)=[ exists k>1,k^3|n])

    Part1 (c=2)

    为了避免重复,强制每一个数(n)的唯一表示为

    (n=acdot b^2(F(a)=1,a<b))

    由于(a<b),所以显然(n>a^3),即(a<n^{frac{1}{3}})

    暴力枚举(a),预处理(n^{frac{1}{3}})中所有的(G(i))即可

    [ ]

    Part (c=3)

    同样的,限制条件为(n=acdot b^3,(G(a)=1,a<b)),得到(a<n^{frac{1}{4}})

    但是由于(c=2,3)两部分有重复,还需额外考虑强制(n)不存在形如(n=a'cdot b'^2)的表示

    假设已知(n=acdot b^3),不存在(n=a'cdot b'^2)的判定条件是

    (a'=frac{n}{F^2(n)}ge F(n)),即(F(n)leq n^{frac{1}{3}})

    同时由于(F(n)=F(acdot b)b)

    得到(F(a,b)leq a^{frac{1}{3}})

    由于等号右边包含(a),考虑枚举(a),易求出(L=F(a),d=frac{a}{L^2}),得到(F(acdot b))的另一种表达形式

    (F(acdot b)=L cdot gcd (d,b)cdot F(frac{b}{gcd(d,b)})leq a^{frac{1}{3}})

    上面的转化意为:(L)(a)中已经成对的部分自然取出,然后优先考虑为(D)匹配(b)中的因数成对,对于剩下的部分再重新计算答案

    [ ]

    化简该式,得到(Lcdot gcd(d,b)F(frac{b}{gcd(d,b)})leq a^{frac{1}{3}})

    式子包含$gcd $,似乎具有莫比乌斯反演的性质

    考虑计算(bin [a+1,(frac{n}{a})^{frac{1}{3}}])的数量

    观察到(a^{frac{1}{3}}leq n^{frac{1}{12}}),上限只有(25)左右,可以考虑直接枚举(F(frac{b}{gcd(b,d)}))

    令枚举的(g=gcd(b,d),F(frac{b}{g})=f),计算(gcd(frac{b}{g},frac{d}{g})=1,gcdot fcdot Lleq a^{frac{1}{3}})(b)的数量

    考虑直接从(frac{b}{g})中把(f^2)的因数提取出来,令(egin{aligned} L'=lceil frac{a+1}{gf^2} ceil,R'=lfloor frac{(frac{n}{a})^{frac{1}{3}}}{gf^2} floor end{aligned}),令(i=frac{b}{gf^2},x=frac{d}{g}),得到新的限制条件式子为

    (gcd(x,f)=1,gcd(i,x)=1,F(i)=1,iin[L',R'])

    在确定了(g,f)之后,需要考虑的限制就是(gcd(i,x)=1,F(i)=1,iin[L',R'])

    由于包含(gcd),不妨用莫比乌斯反演计算该式,得到表达式为

    (Sum=sum_{k|x}mu(k)sum_{iin [L',R']} [k|i ext{and} F(i)=1])

    对于(k),计算(sum_{iin[L',R']}[k|i ext{and} F(i)=1])可以归纳为计算

    (sum_{i=frac{n}{k}} [F(ik)=1]),一共有(n^{frac{1}{3}}ln n)种不同的权值,可以暴力预处理得到

    枚举(d)的因数对于所有的上面的式子计算,可能的(g,f)并不多,可以直接枚举

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pb push_back
    #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
    #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
    
    class SemiPerfectPower {
    public:
    	static const int N=450000,M=20000;
    	int w[N],notpri[N],pri[N],pc,F[N],G[N];
    	vector <int> S[N],Fac[N];
    	ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); }
    	SemiPerfectPower(){
    		// 预处理F,G ,w[i]=mu(i) S[k][i]=sum_{j in [1,i]}  F(i,k)=1
    		rep(i,1,sqrt(N)) rep(j,1,(N-1)/i/i) F[i*i*j]=i;
    		rep(i,2,pow(N,1/3.0)) rep(j,1,(N-1)/i/i/i) G[i*i*i*j]=1;
    		rep(i,1,M-1) for(int j=i;j<M;j+=i) Fac[j].pb(i);
    		w[1]=1;
    		rep(i,2,N-1) {
    			if(!notpri[i]) pri[++pc]=i,w[i]=-1;
    			for(int j=1;i*pri[j]<N && j<=pc;++j) {
    				notpri[i*pri[j]]=1;
    				if(i%pri[j]==0) {
    					w[i*pri[j]]=0;
    					break;
    				} 
    				w[i*pri[j]]=-w[i];
    			}
    		}
    		rep(i,1,N-1) if(w[i]) {
    			S[i].resize(N/i+1);
    			rep(j,1,(N-1)/i) S[i][j]=S[i][j-1]+(F[i*j]==1);
    		}
    	}
    
    	ll Solve2(ll n){
    		ll ans=0,UX=pow(n,1/3.0);
            // 防止浮点误差
    		if((UX+1)*(UX+1)*(UX+1)<=n) UX++;
    		if(UX*UX*UX>n) UX--;
    		rep(i,1,UX) if(F[i]==1) {
    			ll UY=sqrt(n/i);
                // 防止浮点误差
    			if(i*(UY+1)*(UY+1)<=n) UY++;
    			if(i*UY*UY>n) UY--;
    			ans+=max(0ll,UY-i);
    		}
    		return ans;
    	}
    
    	ll Solve3(ll n){
    		ll UX=pow(n,0.25); 
    		// 枚举c的上界
    		ll ans=0;
    		if((UX+1)*(UX+1)*(UX+1)*(UX+1)<=n) UX++;
    		rep(x,1,UX) if(!G[x]) {
    			ll UY=pow(n/x,1.0/3.0),U=pow(x,1/3.0);
    			
    			// 防止浮点误差
    			if((U+1)*(U+1)*(U+1)<=x) U++;
    			if(U*U*U>x) U--;
    			if(x*(UY+1)*(UY+1)*(UY+1)<=n) UY++;
    			if(x*UY*UY*UY>n) UY--;
    
    			int L=F[x],D=x/L/L;
    			for(int G:Fac[D]) {
    				for(int g:Fac[G]) {
    					if(g*L>U) break;
    					rep(f,1,U/g/L) if(gcd(f,D/g)==1) {
    						int L=x/G/f/f,R=UY/G/f/f;
    						ans+=w[G/g]*(S[G/g][R]-S[G/g][L]);
    					}
    				}
    			}
    		}
    		return ans;
    	}
    	ll Solve(ll n) {
    		return Solve2(n)+Solve3(n);
    	}
    	ll count(ll L,ll R) {
    		return Solve(R)-Solve(L-1);
    	}
    };
    
    
  • 相关阅读:
    迭代器模式 -- 大话设计模式
    组合模式 -- 大话设计模式
    备忘录模式 -- 大话设计模式
    totalcmd简单教程--help详解
    Listary Primary
    Cygwin Primary
    Google calendar
    极点郑码标点符号
    Totalcmd 简单教程
    Foobar 简单教程
  • 原文地址:https://www.cnblogs.com/chasedeath/p/14082749.html
Copyright © 2011-2022 走看看