思维题 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 }
编译人生,运行世界!