思维题 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
", ans);
54     }
55 
56     return 0;
57 }
编译人生,运行世界!
原文地址:https://www.cnblogs.com/Running-Time/p/4667014.html