D. GCD and MST(MST&双指针)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D. GCD and MST(MST&双指针)相关的知识,希望对你有一定的参考价值。
D. GCD and MST(MST&双指针)
按照 k r u s k a l kruskal kruskal的思路,先对 a i a_i ai排序。
然后贪心将 a i a_i ai左右扩展至最大是最优的,同时维护一个标记数组 v i s [ i ] vis[i] vis[i]。
表示位置 i i i向右连有一条边。当 w ≥ p w\\ge p w≥p直接 b r e a k break break,因为用 p p p此时更优。
时间复杂度: O ( n l o g n + n ) O(nlogn+n) O(nlogn+n)
// Problem: D. GCD and MST
// Contest: Codeforces - Divide by Zero 2021 and Codeforces Round #714 (Div. 2)
// URL: https://codeforces.ml/problemset/problem/1513/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Date: 2021-08-25 17:59:49
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int t,n,p,val[N];
PII a[N];
bitset<N>vis;
int main(){
scanf("%d",&t);while(t--){
scanf("%d%d",&n,&p);
rep(i,1,n) scanf("%d",&val[i]),a[i]={val[i],i},vis[i]=0;
sort(a+1,a+n+1);
ll s=0;
int c=0;
rep(i,1,n){
int x=a[i].fi,y=a[i].se;
if(x>=p) break;
for(int j=y-1;j>0&&!vis[j]&&val[j]%x==0;j--) c++,vis[j]=1,s+=x;
for(int j=y+1;j<=n&&!vis[j-1]&&val[j]%x==0;j++) c++,vis[j-1]=1,s+=x;
}
s+=1LL*(n-1-c)*p;
printf("%lld\\n",s);
}
return 0;
}
以上是关于D. GCD and MST(MST&双指针)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #599 (Div. 2) D. 0-1 MST(bfs+set)