【题解】
自闭H题。
思路:一段区间的固定起始点的连续子区间的gcd只会在原来的基础上减小或者不变,考虑处理出以第i个元素为右端点的区间gcd的所有取值和取值的最左端点,然后依次求和即可。vr[i][j].first表示第j个gcd取值,vr[i][j].second表示gcd=vr[i][j].first的最左端点。
【代码】
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5*5+5;
const ll mod=1e9+7;
typedef pair <ll,int> P;
vector <P> vr[maxn];
ll a[maxn];
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++){
ll x=a[i]; int y=i;
for(int j=0;j<vr[i-1].size();j++){
int g=__gcd(vr[i-1][j].first,a[i]);
if(g!=x){
vr[i].push_back(P(x,y));
x=g;
}
y=vr[i-1][j].second;
}
vr[i].push_back(P(x,y));