Divide by Zero 2021 and Codeforces Round #714 (Div. 2) D. GCD and MST
提炼
观察gcd()= min()这一条件
发现就是这里面有一个最小值 然后其他值全是最小值的倍数
我们扩展的时候 从最小的开始扩展 最多扩展也是连续的一个区间
这样我们就可以搞出一种贪心的做法
从最小的权值开始扩展 扩展到的就打上标记 这样就是妥妥O(n)了
但是会发现这样可能会wa3 写了个对拍 发现是扩展的时候
多扩展了一些 我们注意扩展到的地方 可以是打过标记的最边上的一个 再多就不礼貌了
6 7
38 3 54 6 2 16
void solve(){
int n,p;cin>>n>>p;
vector<int>a(n+1);
vector<PII>v;
for(int i=1;i<=n;i++){
cin>>a[i];
v.push_back({a[i],i});
}
vector<int>st(n+1);
sort(all(v));
int ans=0,b=0;
for(int i=0;i<n;i++){
auto [w,pos]=v[i];
if(w>=p)break;
if(st[pos])continue;
int j;
for(j=pos+1;j<=n;j++){
if(st[j-1])break;
if(a[j]%a[pos]==0){
b++;
ans+=w;
//st[pos]=st[j]=1;
}else break;
}
int r=j-1;
//cout<<pos<<' '<<j<<endl;
for(j=pos-1;j>=1;j--){
if(st[j+1])break;
if(a[j]%a[pos]==0){
b++;
ans+=w;
//st[pos]=st[j]=1;
}else break;
}
for(int k=j+1;k<=r;k++)st[k]=1;
//cout<<pos<<' '<<j<<endl;
}
cout<<(n-1-b)*p+ans<<endl;
}