给定一张\(n\)个点的图\(G\)。
当\(i < j,gcd(i,j) > 1\),有一条\(i\to j\)的边。
给定点权\(A_i\)。
求选出带权最长反链。
做法:
根据\(diworth\)定理,带权最长反链等于带权可重最小路径覆盖。
于是我们使用二分图模型,费用流即可。
于是
成功输了。
完全输了。
考虑只会选择一个偶数。
其提醒我们思考如何处理选出的数全是奇数的情况。
考虑当\(x < y\)如何可以同时被选。
设\(L_x\)为\(x\)的最小质因数。
给出结论为\(x + L_x > y - L_y\)
考虑若\(x+L_x \leq y+L_y\),考虑如下路径\(x \to x + L_x \to y - L_y \to y\),第三步是因为二者都是偶数。
若\(x + L_x > y - L_y\),则不可能走超过\(2\)步,则考虑是否存在\(x + p = y\)为两者共同约数,由于其全为奇数则不可能。
那么我们只要对所有奇数的区间\([x - L_x,x + L_x]\),选一个点让覆盖其的区间的权值和最大即可。
考虑偶数带来的影响,发现前缀证明不变仅影响到了\(x + p = y\).考虑\(x\)为偶数,考虑若\(z = y - x\),若其不等于\(L_y\),则\(z - L_y >= 2\)不满足第二个条件的先决条件,所以只需考虑\(x + L_y = y\)
那么我们考虑将原本的奇数区间写作\([x - L_x + 1,x + L_x - 1]\),偶数写作\([x,x]\)即可差分实现其。
ARC163E Non-coprime DAG
#include<bits/stdc++.h>
#define ll long long
#define N 1000005
int n;
ll a[N];
ll s[N * 2];
int L[N];
inline void sieve(){
for(int i = 2;i < N;++i){
if(!L[i]){
for(int j = 1;j * i < N;++j)
if(!L[i * j])L[i * j] = i;
}
}
}
ll mx;
int main(){
sieve();
scanf("%d",&n);
for(int i = 1;i <= n;++i)
scanf("%lld",&a[i]);
for(int i = 1;i <= n;++i)
if(i & 1){
s[i - L[i] + 1] += a[i];
s[i + L[i]] -= a[i];
}else{
s[i] += a[i];
s[i + 1] -= a[i];
}
for(int i = 2;i <= n * 2;++i)
s[i] = s[i] + s[i - 1],mx = std::max(mx,s[i]);
std::cout<<mx + a[1]<<"\n";
}