LOJ6482. LJJ 爱数数

题目描述:戳这里
题解:

1 a + 1 b = 1 c \frac{1}{a}+\frac{1}{b}=\frac{1}{c} a1+b1=c1
( a + b ) c = a b (a+b)c=ab (a+b)c=ab
令 g = g c d ( a , b ) , A = a g , B = b g 令g=gcd(a,b),A=\frac{a}{g},B=\frac{b}{g} g=gcd(a,b),A=ga,B=gb
( A + B ) c = A B g (A+B)c=ABg (A+B)c=ABg
由 于 g 要 整 除 等 式 左 边 的 东 西 , 然 而 g 不 整 除 c , 所 以 g 整 除 A + B , 那 么 可 以 除 过 去 由于g要整除等式左边的东西,然而g不整除c,所以g整除A+B,那么可以除过去 g西gcgA+B
A + B g = A B c \frac{A+B}{g}=\frac{AB}{c} gA+B=cAB
我们假设这个式子两边都等于p。
那么如果 p ! = 1 p!=1 p!=1,说明p整除A或者B,p不可能同时整除A和B,因为A、B互质。但是p要整除 A + B A+B A+B,所以不可能成立。
所以可以推出 p = 1 p=1 p=1
那么就可以推出两条式子:
A + B = g , 即 是 : a + b = g 2 A+B=g,即是:a+b=g^2 A+B=g,:a+b=g2
c = A B , 就 是 : c = a b g 2 c=AB,就是:c=\frac{ab}{g^2} c=AB,c=g2ab

那么接下来问题就比较好处理了:
由于 a , b &lt; = 1 0 12 a,b&lt;=10^{12} a,b<=1012,那么 a + b = 2 ∗ 1 0 12 = 1 0 6 级 别 \sqrt{a+b}=\sqrt{2*10^{12}}=10^6级别 a+b =21012 =106
我们先枚举gcd(a,b)=g,然后假设a=i*g,那么可以列出和式:
∑ g = 1 2 n ∑ i = 1 ⌊ n g ⌋ [ g c d ( i g , g 2 − i g ) = g ] \sum_{g=1}^{\sqrt{2n}}\sum_{i=1}^{\lfloor{\frac{n}{g}}\rfloor}[gcd(ig,g^2-ig)=g] g=12n i=1gn[gcd(ig,g2ig)=g]
化简一下:
∑ g = 1 2 n ∑ i = 1 ⌊ n g ⌋ [ g c d ( i , g − i ) = 1 ] \sum_{g=1}^{\sqrt{2n}}\sum_{i=1}^{\lfloor{\frac{n}{g}}\rfloor}[gcd(i,g-i)=1] g=12n i=1gn[gcd(i,gi)=1]
由于辗转相减的性质,可知:
∑ g = 1 2 n ∑ i = 1 ⌊ n g ⌋ [ g c d ( i , g ) = 1 ] \sum_{g=1}^{\sqrt{2n}}\sum_{i=1}^{\lfloor{\frac{n}{g}}\rfloor}[gcd(i,g)=1] g=12n i=1gn[gcd(i,g)=1]
即是求一定范围内与g互质的数的个数。
前面还有一些小问题,实际上我们对i的限制范围有一些不准确。
1 &lt; = g 2 − i g &lt; = n 1&lt;=g^2-ig&lt;=n 1<=g2ig<=n
g − ⌊ n g ⌋ &lt; = i &lt; = g − 1 g-\lfloor\frac{n}{g}\rfloor&lt;=i&lt;=g-1 ggn<=i<=g1
与原范围合并一下,可以化简为:
m a x ( 1 , g − ⌊ n g ⌋ ) &lt; = i &lt; = m i n ( g − 1 , ⌊ n g ⌋ ) max(1,g-\lfloor\frac{n}{g}\rfloor)&lt;=i&lt;=min(g-1,\lfloor\frac{n}{g}\rfloor) max(1,ggn)<=i<=min(g1,gn)
所以原式可以写成:
∑ g = 1 2 n ∑ i = m a x ( 1 , g − ⌊ n g ⌋ ) m i n ( g − 1 , ⌊ n g ⌋ ) [ g c d ( i , g ) = 1 ] \sum_{g=1}^{\sqrt{2n}}\sum_{i=max(1,g-\lfloor\frac{n}{g}\rfloor)}^{min(g-1,\lfloor\frac{n}{g}\rfloor)}[gcd(i,g)=1] g=12n i=max(1,ggn)min(g1,gn)[gcd(i,g)=1]

接下来只要求 g c d ( i , g ) = 1 gcd(i,g)=1 gcd(i,g)=1的对数了。
这个可以直接用莫比乌斯反演,对r搞一下,l-1搞一下,然后相减即可。
时间复杂度 O ( n l o g ( n ) ) O(\sqrt{n}log(\sqrt{n})) O(n log(n ))

代码如下:

#pragma GCC optimze("Ofast","inline")
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e6+5;
ll n,ans;
int mu[maxn],su[maxn],lnk[maxn],nxt[16*maxn],son[16*maxn],tot;
bool vis[maxn];
void make_mu(){
	mu[1]=1; int m=0;
	for (int i=2;i<=2e6;i++){
		if (!vis[i]) su[++m]=i,mu[i]=-1;
		for (int j=1;j<=m&&1ll*su[j]*i<=2e6;j++){
			vis[i*su[j]]=1;
			if (i%su[j]==0) {mu[i*su[j]]=0; break;}
			else mu[i*su[j]]=-mu[i];
		}
	}
}
ll doit(ll x,ll y){
	ll ret=0;
	for (int j=lnk[y];j;j=nxt[j])
		if (y%son[j]==0) ret+=mu[son[j]]*(x/son[j]);
	return ret;
}
void add(int x,int y){
	son[++tot]=y,nxt[tot]=lnk[x],lnk[x]=tot;
}
int main(){
	scanf("%lld",&n);
	make_mu();
	for (int i=1;1ll*i*i<=2*n;i++)
		if(mu[i])
		for (int j=1;1ll*j*i*j*i<=2*n;j++)
			add(i*j,i);
	for (ll g=1ll;g*g<=2*n;g++)
		ans+=doit(min(n/g,g-1),g)-doit(max(1ll,g-n/g)-1,g);
	printf("%lld\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值