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;
}
posted @ 2023-02-24 21:28  ycllz  阅读(23)  评论(0)    收藏  举报