https://codeforces.com/contest/1513/problem/D
从小到大枚举数字,然后嗯往两边拓展,标记一下每条边被替代没有,每条边最多被替代一次
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,k,cnt,tot,cas;ll p,ans;
ll a[maxl];
struct node
{
ll val,id;
}b[maxl];
bool vis[maxl];
char s[maxl];
inline bool cmp(const node &a,const node &b)
{
return a.val<b.val;
}
inline void prework()
{
scanf("%d%lld",&n,&p);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]),b[i]=node{a[i],i};
sort(b+1,b+1+n,cmp);
}
inline void mainwork()
{
ans=p*(n-1);
for(int i=1;i<=n;i++)
vis[i]=false;
for(int i=1;i<=n;i++)
{
ll x=b[i].val;
if(x>=p)
break;
for(int j=b[i].id+1;j<=n;j++)
{
if(vis[j-1] || __gcd(x,a[j])!=x)
break;
vis[j-1]=true;ans-=p;ans+=x;
}
for(int j=b[i].id-1;j>=1;j--)
{
if(vis[j] || __gcd(x,a[j])!=x)
break;
vis[j]=true;ans-=p;ans+=x;
}
}
}
inline void print()
{
printf("%lld\n",ans);
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}