思维题 HDOJ 5288 OO’s Sequence

 

题目传送门

 1 /*  2  定义两个数组,l[i]和r[i]表示第i个数左侧右侧接近它且值是a[i]因子的位置,  3  第i个数被选择后贡献的值是(r[i]-i)*(i-l[i]),每个数都枚举它的因子,更新l[i], r[i],复杂度O(n*sqrt(a[i]))  4 */  5 #include <cstdio>  6 #include <cmath>  7 #include <algorithm>  8 #include <cstring>  9 #include <map> 10 using namespace std; 11 12 const int MAXN = 1e5 + 10; 13 const int INF = 0x3f3f3f3f; 14 const int MOD = 1e9 + 7; 15 int a[MAXN]; 16 int l[MAXN], r[MAXN]; 17 int pos[10010]; 18 19 int main(void) { //HDOJ 5288 OO’s Sequence 20 //freopen ("1001.in", "r", stdin); 21 int n; 22 while (scanf ("%d", &n) == 1) { 23 for (int i=1; i<=n; ++i) { 24 scanf ("%d", &a[i]); 25  } 26 27 int ans = 0; 28 memset (pos, 0, sizeof (pos)); 29 memset (l, 0, sizeof (l)); 30 for (int i=1; i<=n; ++i) { 31 for (int j=1; j<=sqrt (a[i]); ++j) { 32 if (a[i] % j == 0) { 33 if (pos[j] > l[i]) l[i] = pos[j]; 34 if (pos[a[i]/j] > l[i]) l[i] = pos[a[i]/j]; 35  } 36  } 37 pos[a[i]] = i; 38  } 39 for (int i=1; i<=10000; ++i) pos[i] = n + 1; 40 for (int i=1; i<=n; ++i) r[i] = n + 1; 41 for (int i=n; i>=1; --i) { 42 for (int j=1; j<=sqrt (a[i]); ++j) { 43 if (a[i] % j == 0) { 44 if (pos[j] < r[i]) r[i] = pos[j]; 45 if (pos[a[i]/j] < r[i]) r[i] = pos[a[i]/j]; 46  } 47  } 48 pos[a[i]] = i; 49  } 50 for (int i=1; i<=n; ++i) { 51 ans = (ans + (r[i] - i) * (i - l[i]) % MOD) % MOD; 52  } 53 printf ("%d\n", ans); 54  } 55 56 return 0; 57 }

 

你可能感兴趣的:(sequence)