题面传送门
月赛中的简单题。
考虑推一波式子。
设
g
=
g
c
d
(
b
i
,
b
j
)
g=gcd(b_i,b_j)
g=gcd(bi,bj)
那么原式就是
b
i
+
b
j
+
g
=
b
i
×
b
j
g
b_i+b_j+g=\frac{b_i\times b_j}{g}
bi+bj+g=gbi×bj
b
i
g
+
b
j
g
+
1
=
b
i
g
×
b
j
g
\frac{b_i}{g}+\frac{b_j}{g}+1=\frac{b_i}{g}\times \frac{b_j}{g}
gbi+gbj+1=gbi×gbj
换元,设
x
=
b
i
g
,
y
=
b
j
g
x=\frac{b_i}{g},y=\frac{b_j}{g}
x=gbi,y=gbj
那么
a
+
b
+
1
=
a
b
a+b+1=ab
a+b+1=ab
(
a
−
1
)
(
b
−
1
)
=
2
(a-1)(b-1)=2
(a−1)(b−1)=2
根据题意又有
b
i
<
b
j
b_i<b_j
bi<bj,所以
b
i
×
1.5
=
b
j
b_i\times 1.5=b_j
bi×1.5=bj
那么建图跑最长链即可。
注意相同也要连边
代码实现:
#include<cstdio>
#include<map>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int n,m,k,x,y,z,a[300039],p[300039],in[300039],now;
long long ans,tot;
map<int,int>q,f;
struct yyy{int to,w,z;};
int main(){
register int i;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);tot=max(tot,a[i]);
if(q[a[i]]) p[q[a[i]]]=i,in[i]++;
q[a[i]]=i;
if(!f[a[i]])f[a[i]]=i;
}
for(i=1;i<=n;i++){
if(a[i]%2==0&&f[a[i]/2*3]&&!p[i]) p[i]=f[a[i]/2*3],in[p[i]]++;
}
for(i=1;i<=n;i++){
if(!in[i]&&p[i]){
ans=a[i];
now=p[i];
while(now){
ans+=a[now];
now=p[now];
}
tot=max(tot,ans);
}
}
printf("%lld\n",tot);
}