fafa法数 - 莫比乌斯反演 - 数论

要说神仙数论题
老爷爷最强无敌
(咦怎么这么押韵的说)
题目大意:
给你 L , R L,R L,R,求有多少 n ∈ [ L , R ] n\in[L,R] n[L,R],满足存在 1 ≤ a &lt; b , c ≥ 1 1\le a&lt;b,c\geq1 1a<b,c1,使得 n = a b c n=ab^c n=abc 1 ≤ L ≤ R ≤ 8 × 1 0 16 1\le L\le R\le 8\times 10^{16} 1LR8×1016
题解:
首先当c确定时,为了避免重复计数,我们要保证a中的质因子的指数小于c。
其次,从这个角度出发, c ≥ 4 c\geq4 c4都是没有意义的。
因为若 2 ∣ c 2|c 2c,则 n = a ( b 2 ) c 2 n=a(b^2)^\frac c2 n=a(b2)2c,否则 n = a b ( b 2 ) c − 1 2 n=ab(b^2)^{\frac{c-1}{2}} n=ab(b2)2c1,可以验证这两种情况都是合法的。
c = 2 c=2 c=2,则有 n = a b 2 &gt; a 3 n=ab^2&gt;a^3 n=ab2>a3 a &lt; n 3 a&lt;\sqrt[3]{n} a<3n ,因此(令 p 2 ( n ) , p 3 ( n ) p_2(n),p_3(n) p2(n),p3(n)分别表示n中是否含平方、立方因子)对答案的贡献是:
∑ 1 ≤ a &lt; n 3 p 2 ( a ) ( ⌊ n a ⌋ − a ) \sum_{1\le a&lt;\sqrt[3]{n}}p_2(a)\left(\left\lfloor\sqrt{\frac na}\right\rfloor-a\right) 1a<3n p2(a)(an a)
c = 3 c=3 c=3,则这么计算是有问题的,因为例如 1 × 4 3 = 1 × 8 2 1\times4^3=1\times8^2 1×43=1×82,可能某些 c = 3 c=3 c=3会被 c = 2 c=2 c=2计算。
n = b y 3 n=by^3 n=by3,我们知道其中一种可行但可能不合法的 c = 2 c=2 c=2的情况是 n = b y × y 2 n=by\times y^2 n=by×y2。若想使得其可能合法,就要将 b y by by中的平方质因子取尽,即要找到一个最大的 k k k,满足 k 2 ∣ b y k^2|by k2by,并变换 n = b y k 2 × ( k y ) 2 n=\frac{by}{k^2}\times(ky)^2 n=k2by×(ky)2
这样仍然可能是没有被计算的,因为 c = 2 c=2 c=2的情况只会计算 b y k 2 &lt; k y \frac{by}{k^2}&lt;ky k2by<ky的部分,也就是 b y k 2 ≥ k y \frac{by}{k^2}\geq ky k2byky k ≤ b 3 k\le\sqrt[3]{b} k3b 的部分是属于 c = 3 c=3 c=3的答案但是不会被 c = 2 c=2 c=2统计到。
因此我们可以类似的枚举 b , k , y b,k,y b,k,y来计算答案:
∑ 1 ≤ b &lt; n 4 p 3 ( b ) ∑ b &lt; y ≤ n b 3 ∑ 1 ≤ k ≤ b 3 [ k 2 ∣ b y ] p 2 ( b y k 2 ) \sum_{1\le b&lt;\sqrt[4]{n}}p_3(b)\sum_{b&lt;y\le\sqrt[3]{\frac nb}}\sum_{1\le k\le\sqrt[3]{b}}\left[k^2\left|\right.by\right]p_2\left(\frac{by}{k^2}\right) 1b<4n p3(b)b<y3bn 1k3b [k2by]p2(k2by)
进一步简单的数论转化,令:
g = ( k 2 , b ) , k ′ = k 2 g , b ′ = b g , y ′ = y k ′ g=\left(k^2,b\right),k&#x27;=\frac {k^2}g,b&#x27;=\frac bg,y&#x27;=\frac y{k&#x27;} g=(k2,b),k=gk2,b=gb,y=ky
则:
[ k 2 ∣ b y ] = [ k ′ g ∣ b ′ g y ] = [ k ′ ∣ b ′ y ] = [ k ′ ∣ y ] \left[k^2\left|\right.by\right]=[k&#x27;g|b&#x27;gy]=[k&#x27;|b&#x27;y]=[k&#x27;|y] [k2by]=[kgbgy]=[kby]=[ky]
同时:
p 2 ( b y k 2 ) = p 2 ( b ′ y ′ ) = p 2 ( b ′ ) p 2 ( y ′ ) [ b ′ ⊥ y ′ ] p_2\left(\frac{by}{k^2}\right)=p_2\left(b&#x27;y&#x27;\right)=p_2\left(b&#x27;\right)p_2\left(y&#x27;\right)\left[b&#x27;\perp y&#x27;\right] p2(k2by)=p2(by)=p2(b)p2(y)[by]
对后面的 [ b ′ ⊥ y ′ ] \left[b&#x27;\perp y&#x27;\right] [by]做莫比乌斯反演并化简整个式子(省略一些简单推导):
∑ 1 ≤ b &lt; n 4 p 3 ( b ) ∑ 1 ≤ k ≤ b 3 p 2 ( b ′ ) ∑ d ∣ b ′ μ ( d ) ∑ b k ′ &lt; y ′ ≤ 1 k ′ n b 3 p 2 ( y ′ ) [ d ∣ y ′ ] \sum_{1\le b&lt;\sqrt[4]{n}}p_3(b)\sum_{1\le k\le\sqrt[3]{b}}p_2\left(b&#x27;\right)\sum_{d|b&#x27;}\mu(d)\sum_{\frac{b}{k&#x27;}&lt;y&#x27;\le\frac1{k&#x27;}\sqrt[3]{\frac nb}}p_2\left(y&#x27;\right)\left[d\left|\right.y&#x27;\right] 1b<4n p3(b)1k3b p2(b)dbμ(d)kb<yk13bn p2(y)[dy]
c n t d ( m ) = ∑ i = 1 m p 2 ( i d ) cnt_d(m)=\sum_{i=1}^mp_2(id) cntd(m)=i=1mp2(id),则上式等于:
∑ 1 ≤ b &lt; n 4 p 3 ( b ) ∑ 1 ≤ k ≤ b 3 p 2 ( b ′ ) ∑ d ∣ b ′ μ ( d ) ( c n t d ( ⌊ 1 k ′ d n b 3 ⌋ ) − c n t d ( ⌊ b k ′ d ⌋ ) ) \sum_{1\le b&lt;\sqrt[4]{n}}p_3(b)\sum_{1\le k\le\sqrt[3]{b}}p_2\left(b&#x27;\right)\sum_{d|b&#x27;}\mu(d)\left(cnt_d\left(\left\lfloor\frac{1}{k&#x27;d}\sqrt[3]{\frac nb}\right\rfloor\right)-cnt_d\left(\left\lfloor\frac b{k&#x27;d}\right\rfloor\right)\right) 1b<4n p3(b)1k3b p2(b)dbμ(d)(cntd(kd13bn )cntd(kdb))
这样暴力枚举 b , k , d b,k,d b,k,d,可以大概算出复杂度不会并且远远不超过 O ( n 5 12 ) O\left(n^{\frac5{12}}\right) O(n125),预处理前 O ( n 1 3 ) O\left(n^\frac 13\right) O(n31) p 2 ( n ) p_2(n) p2(n)以及前 O ( n 1 4 ) O\left(n^{\frac 14}\right) O(n41) p 3 p_3 p3 μ \mu μ,还有 c n t d ( m ) cnt_d(m) cntd(m)即可,其中 O ( d ) = O ( n 1 4 ) , O ( m ) = O ( n 3 d ) O(d)=O\left(n^{\frac 14}\right),O(m)=O\left(\frac{\sqrt[3]n}{d}\right) O(d)=O(n41),O(m)=O(d3n )
哇终于写(chao)完了 Q w Q \mathrm{QwQ} QwQ

#include<bits/stdc++.h>
#define gc getchar()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define N3 440000
#define N4 100000
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
vector<int> dvs[N3],cnt[N4];
int p2[N3],p3[N3],mu[N3],pri[N3],mnp[N3],np[N3];
inline int gcd(int a,int b) { return a?gcd(b%a,a):b; }
inline int Mysqrt(lint x)
{
	int L=1,R=1000000000,mid=(L+R)>>1;//1e9
	while(L<=R)
	{
		if((lint)mid*mid<=x) L=mid+1;
		else R=mid-1;mid=(L+R)>>1;
	}
	return R;
}
inline int Mycbrt(lint x)
{
	int L=1,R=1000000,mid=(L+R)>>1;//1e6
	while(L<=R)
	{
		if((lint)mid*mid*mid<=x) L=mid+1;
		else R=mid-1;mid=(L+R)>>1;
	}
	return R;
}
inline lint calc(lint n)
{
	if(!n) return 0;lint ans=0;
	for(int a=1;(lint)a*a*a<n;a++)
		if(p2[a]) ans+=Mysqrt(n/a)-a;
	for(int b=1;(lint)b*b*b*b<n;b++) if(p3[b])
		for(int k=1;k*k*k<=b;k++)
		{
			int k2dg=gcd(k*k,b),kp=k*k/k2dg,bp=b/k2dg;
			if(!p2[bp]) continue;
			Rep(i,dvs[bp])
			{
				int d=dvs[bp][i],s=b/kp,t=Mycbrt(n/b)/kp;
				ans+=mu[d]*(cnt[d][t/d]-cnt[d][s/d]);
			}
		}
	return ans;
}
inline int get_mnp_mu(int n)
{
	mnp[1]=1,mu[1]=1;
	for(int i=2,cnt=0;i<=n;i++)
	{
		if(!np[i]) pri[++cnt]=i,mnp[i]=i,mu[i]=-1;
		for(int j=1;j<=cnt&&pri[j]<=n/i;j++)
		{
			int x=pri[j]*i;np[x]=1,mnp[x]=pri[j],mu[x]=-mu[i];
			if(i%pri[j]==0) { mu[x]=0;break; }
		}
	}
	return 0;
}
inline int prelude(lint n)
{
	int n3=Mycbrt(n)+1,n4=Mysqrt(Mysqrt(n))+1;
	get_mnp_mu(n3);
	rep(i,1,n3)
	{
		p2[i]=p3[i]=1;int x=i;
		while(x>1)
		{
			int t=mnp[x],cnt=0;while(x%t==0) x/=t,cnt++;
			if(cnt>1) p2[i]=0;if(cnt>2) p3[i]=0;
			if(!p2[i]&&!p3[i]) break;
		}
	}
	rep(i,1,n4) rep(j,1,n4/i) if(mu[j]) dvs[i*j].pb(j);
	rep(d,1,n4)
	{
		cnt[d].resize(n3/d+1),cnt[d][0]=0;
		rep(i,1,(int)cnt[d].size()-1)
			cnt[d][i]=cnt[d][i-1]+p2[i*d];
	}
	return 0;
}
int main()
{
	lint L,R;cin>>L>>R;prelude(R);
	return cout<<calc(R)-calc(L-1)<<endl,0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MinGW-w64是一个开源的软件开发工具包,用于Windows平台上的C和C++编程。它是MinGW的一个分支,支持64位操作系统。使用MinGW-w64可以在Windows上编译和运行C和C++程序。 在使用MinGW-w64之前,需要先下载并安装它。可以从MinGW-w64官方网站(http://mingw-w64.org/)下载安装程序。安装完成后,会在系统中创建一个mingw64文件夹,其中包含一系列的文件夹,其中的bin文件夹存放了编译工具。你可以将这个bin目录添加到系统的环境变量中,这样就可以在命令行或者其他开发环境中直接使用MinGW-w64的编译工具了。 使用MinGW-w64进行编程时,可以使用命令行工具来编译和运行程序。在命令行中,可以使用gcc来编译C程序,使用g++来编译C++程序。具体的编译命令可以根据不同的需求进行调整,比如指定输出文件名、调试选项等。 此外,MinGW-w64也支持集成开发环境(IDE)如Code::Blocks、Eclipse等。你可以根据自己的喜好选择适合自己的开发环境,并按照它们的指引进行配置和使用。 总结起来,MinGW-w64是一个用于Windows平台上的C和C++编程工具包,提供了编译工具和一些必要的库文件,可以用于开发和运行C和C++程序。你可以通过命令行工具或者集成开发环境来使用它。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [MinGW-w64安装教程——著名C/C++编译器GCC的Windows版本](https://blog.csdn.net/afafa1314/article/details/102021997)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值