题意:给出n个数a【1】~a【n】,问里面有多少个区间满足:对于该区间内任意一个数,区间内没有任何数能被其整除。
首先预处理出所有数的因子(1~10000),然后枚举每个数a【i】的因子,对于每个因子找出其在i左边和右边最靠近i的位置,l, r,那么这个数的贡献就是(i-l+1)*(r-i+1).注意要%mod
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cmath>
#include <time.h>
#include <vector>
#include <cstdio>
#include <string>
#include <iomanip>
///cout << fixed << setprecision(13) << (double) x << endl;
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define ls rt << 1
#define rs rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
#define Mp(a, b) make_pair(a, b)
#define asd puts("asdasdasdasdasdf");
typedef long long ll;
//typedef __int64 LL;
const int inf = 0x3f3f3f3f;
const int N = 100010;
const int mod = 1e9+7;
int n;
int a[N];
vector <int> yue[N]; //每个数的约数
vector <int> pos[N]; //每个约数出现的位置
int main()
{
for( int i = 1; i <= 10000; ++i ) {
yue[i].clear();
for( int j = 1; j * j <= i; ++j ) {
if( i % j == 0 ) {
yue[i].push_back(j);
if( i / j != j )
yue[i].push_back(i/j);
}
}
}
while( ~scanf("%d", &n) ) {
for( int i = 1; i <= 100000; ++i )
pos[i].clear();
for( int i = 1; i <= n; ++i ) {
scanf("%d", &a[i]);
pos[a[i]].push_back(i);
}
ll ans = 0;
for( int i = 1; i <= n; ++i ) {
ll l = 1, r = n;
int sz = yue[a[i]].size();
for( int j = 0; j < sz; ++j ) {
int x = yue[a[i]][j]; //x为a[i]的约数
int siz = pos[x].size();
if( siz == 0 )
continue;
if( pos[x][siz-1] <= i ) { //所有数在i左边
if( pos[x][siz-1] < i )
l = max( l, 1LL*pos[x][siz-1]+1 );
else {
if( siz >= 2 )
l = max( l, 1LL*pos[x][siz-2]+1 );
}
continue;
}
if( pos[x][0] >= i ) { //在i右边
if( pos[x][0] > i )
r = min( r, 1LL*pos[x][0]-1 );
else {
if( siz >= 2 )
r = min( r, 1LL*pos[x][1]-1 );
}
continue;
}
else { //在i两边
int pp = lower_bound( pos[x].begin(), pos[x].end(), i )- pos[x].begin();
l = max( l, 1LL*pos[x][pp-1]+1 );
if( pos[x][pp] == i )
pp++;
//if( pp < siz )
r = min( r, 1LL*pos[x][pp]-1 );
}
}
ans += 1LL*(1LL*i-l+1) * (r-1LL*i+1) % mod;
ans %= mod;
}
printf("%lld\n", ans);
}
return 0;
}