HDU - 2866 Special Prime(数论+数学证明)
题目大意:给定一个区间,判断形如
n
3
+
n
2
p
=
m
3
n^3+n^2p=m^3
n3+n2p=m3这样的非线性丢番图方程是否存在正整数解
(
n
0
,
m
0
)
(n_0,m_0)
(n0,m0),其中
p
p
p为区间中的任一质数。输出这个区间中使得上述方程有解的质数的数量。
题解:若
p
∣
n
p \mid n
p∣n,令
k
=
n
/
p
k=n/p
k=n/p,那么有方程
k
3
p
3
+
k
2
p
3
=
m
3
⇒
p
3
(
k
3
+
k
2
)
=
m
3
k^3p^3+k^2p^3=m^3 \Rightarrow p^3(k^3+k^2)=m^3
k3p3+k2p3=m3⇒p3(k3+k2)=m3。显然,当且仅当
k
3
+
k
2
k^3+k^2
k3+k2为立方数时,上述方程成立。又
k
3
+
k
2
=
k
2
(
k
+
1
)
k^3+k^2=k^2(k+1)
k3+k2=k2(k+1)且
g
c
d
(
k
,
k
+
1
)
=
1
gcd(k,k+1)=1
gcd(k,k+1)=1。我们可以分两种情况讨论。
(
1
)
:
(1):
(1): 对于
∀
k
≥
2
\forall k\geq 2
∀k≥2,
k
2
(
k
+
1
)
k^2(k+1)
k2(k+1)可质因数分解为
p
1
2
s
1
p
2
2
s
2
⋯
p
r
2
s
r
q
1
t
1
q
2
t
2
⋯
q
w
t
w
p_1^{2s_1}p_2^{2s_2}\cdots p_r^{2s_r}q_1^{t_1}q_2^{t_2}\cdots q_w^{t_w}
p12s1p22s2⋯pr2srq1t1q2t2⋯qwtw,其中
k
=
p
1
s
1
p
2
s
2
⋯
p
r
s
r
k=p_1^{s_1}p_2^{s_2}\cdots p_r^{s_r}
k=p1s1p2s2⋯prsr,
k
+
1
=
q
1
t
1
q
2
t
2
⋯
q
w
t
w
k+1=q_1^{t_1}q_2^{t_2}\cdots q_w^{t_w}
k+1=q1t1q2t2⋯qwtw,且
{
p
1
,
p
2
,
⋯
,
p
r
}
∩
{
q
1
,
q
2
,
⋯
,
q
w
}
=
∅
\{p_1,p_2,\cdots ,p_r\} \cap \{q_1,q_2,\cdots ,q_w\}=\varnothing
{p1,p2,⋯,pr}∩{q1,q2,⋯,qw}=∅,此时当且仅当
s
1
%
3
=
0
,
s
2
%
3
=
0
,
⋯
,
s
r
%
3
=
0
,
t
1
%
3
=
0
,
t
2
%
3
=
0
,
⋯
,
t
w
%
3
=
0
s_1\%3=0,s_2\%3=0,\cdots,s_r\%3=0,t_1\%3=0,t_2\%3=0,\cdots,t_w\%3=0
s1%3=0,s2%3=0,⋯,sr%3=0,t1%3=0,t2%3=0,⋯,tw%3=0成立时,
k
3
+
k
2
k^3+k^2
k3+k2才为立方数,上述等式的成立与
k
k
k和
k
+
1
k+1
k+1同时为立方数为等价命题,而这显然是不可能的。
(
2
)
:
(2):
(2):当
k
=
1
k=1
k=1时,
k
3
+
k
2
=
1
+
1
=
2
k^3+k^2=1+1=2
k3+k2=1+1=2,
2
2
2不是立方数。
综上所述,当
p
∣
n
p \mid n
p∣n时,方程
n
3
+
n
2
p
=
m
3
n^3+n^2p=m^3
n3+n2p=m3不存在正整数解。
若
p
∤
n
p \nmid n
p∤n,可以对方程左边的
n
2
(
n
+
p
)
n^2(n+p)
n2(n+p)的
n
2
n^2
n2进行质因数分解。有
p
1
2
s
1
p
2
2
s
2
⋯
p
r
2
s
r
(
n
+
p
)
p_1^{2s_1}p_2^{2s_2}\cdots p_r^{2s_r}(n+p)
p12s1p22s2⋯pr2sr(n+p),若
∃
s
i
∈
{
s
1
,
s
2
,
⋯
,
s
r
}
,
s
.
t
.
3
∤
s
i
\exist s_i \in \{s_1,s_2,\cdots,s_r\},s.t.\space 3\nmid s_i
∃si∈{s1,s2,⋯,sr},s.t. 3∤si,那么
n
+
p
n+p
n+p的质因数分解中,必有质因子
p
i
3
−
(
2
s
i
m
o
d
3
)
+
x
(
x
≥
0
)
p_i^{3-(2s_i\space mod \space 3)+x}(x\geq0)
pi3−(2si mod 3)+x(x≥0),否则方程右边不满足立方数的定义。令
n
+
p
=
y
p
i
3
−
(
2
s
i
m
o
d
3
)
+
x
n+p=yp_i^{3-(2s_i\space mod \space 3)+x}
n+p=ypi3−(2si mod 3)+x,那么我们有:
p
=
n
+
p
−
n
p
=
y
p
i
3
−
(
2
s
i
m
o
d
3
)
+
x
−
p
1
s
1
p
2
s
2
⋯
p
r
s
r
p
=
p
i
(
y
p
i
2
−
(
2
s
i
m
o
d
3
)
+
x
−
p
1
s
1
p
2
s
2
⋯
p
i
s
i
−
1
⋯
p
r
s
r
)
p=n+p-n\\p=yp_i^{3-(2s_i\space mod \space 3)+x}-p_1^{s_1}p_2^{s_2}\cdots p_r^{s_r}\\p=p_i(yp_i^{2-(2s_i\space mod \space 3)+x}-p_1^{s_1}p_2^{s_2}\cdots p_i^{s_i-1}\cdots p_r^{s_r})
p=n+p−np=ypi3−(2si mod 3)+x−p1s1p2s2⋯prsrp=pi(ypi2−(2si mod 3)+x−p1s1p2s2⋯pisi−1⋯prsr)
说明
y
p
i
2
−
(
2
s
i
m
o
d
3
)
+
x
−
p
1
s
1
p
2
s
2
⋯
p
i
s
i
−
1
⋯
p
r
s
r
yp_i^{2-(2s_i\space mod \space 3)+x}-p_1^{s_1}p_2^{s_2}\cdots p_i^{s_i-1}\cdots p_r^{s_r}
ypi2−(2si mod 3)+x−p1s1p2s2⋯pisi−1⋯prsr必须要等于
1
1
1,此时有
p
i
=
p
⇒
p
∣
n
p_i=p\Rightarrow p \mid n
pi=p⇒p∣n,与题设矛盾。
由上述可知,
n
2
n^2
n2只能为一立方数,同时
n
+
p
n+p
n+p也为一立方数。设
n
2
=
β
2
∗
3
,
n
+
p
=
α
3
n^2=\beta^{2*3},n+p=\alpha^3
n2=β2∗3,n+p=α3,则有:
p
=
n
+
p
−
n
p
=
α
3
−
β
3
p
=
(
α
−
β
)
(
α
2
+
α
β
+
β
2
)
p=n+p-n \\p= \alpha^3-\beta^3\\p=(\alpha-\beta)(\alpha^2+\alpha\beta+\beta^2)
p=n+p−np=α3−β3p=(α−β)(α2+αβ+β2)
此时
α
−
β
\alpha-\beta
α−β必须等于
1
1
1,否则与
p
p
p为质数的定义矛盾。
综上所述,当且仅当
p
p
p可以表为两个相邻正整数的立方数之差时,方程
n
3
+
n
2
p
=
m
3
n^3+n^2p=m^3
n3+n2p=m3有唯一一组正整数解
(
n
0
,
m
0
)
(n_0,m_0)
(n0,m0),
n
0
n_0
n0为那两个相邻正整数中较小的那一个。
那么问题便转化为:对于一给定区间,求区间中有多少质数能表为两个相邻正整数的立方数之差。
下面是AC代码。
#include<bits/stdc++.h>
using namespace std;
struct fastio{fastio(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}}fio;
#define int long long
#define endl '\n'
#define all(x) x.begin(),x.end()
const int N=1e6;
vector<int> prime,res(N+1),judge(N+1,1);
void init(){
judge[0]=judge[1]=0;
for(int i=2;i<=N;++i){
if(judge[i]==1) prime.push_back(i);
for(int j=0;i*prime[j]<=N;++j){
judge[i*prime[j]]=0;
if(i%prime[j]==0) break;
}
}
for(int i=1;(i+1)*(i+1)*(i+1)-i*i*i<=N;++i){
if(judge[(i+1)*(i+1)*(i+1)-i*i*i]==1) {
++judge[(i+1)*(i+1)*(i+1)-i*i*i];
}
}
res[0]=res[1]=0;
for(int i=2;i<=N;++i){
res[i]=res[i-1]+(judge[i]==2?1:0);
}
}
signed main(){
int l;
init();
while(cin>>l){
if(res[l]==0) cout<<"No Special Prime!"<<endl;
else cout<<res[l]<<endl;
}
}