hdu 5288 思路题

如果枚举区间的话是O(n^2)的复杂度一定会T,所以考虑每个数a[i]对答案的贡献,则只需找到a[i]的约数中在左边最靠近a[i]的和在右边最靠近a[i]的那两个约数位置,然后扫一遍统计答案即可。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 const int INF = 0x3f;
 8 const int MOD = 1000000007;
 9 const int N = 100001;
10 int a[N];
11 int l[N];
12 int r[N];
13 int mp[N];
14 
15 int main ()
16 {
17     int n;
18     while ( scanf("%d", &n) != EOF )
19     {
20         for ( int i = 1; i <= n; i++ )
21         {
22             scanf("%d", a + i);
23             l[i] = 0;
24             r[i] = n + 1;
25         }
26         memset( mp, -1, sizeof(mp) );
27         for ( int i = 1; i <= n; i++ )
28         {
29             for ( int j = 1; j * j <= a[i]; j++ )
30             {
31                 if ( a[i] % j == 0 )
32                 {
33                     l[i] = max( l[i], mp[j] );
34                     l[i] = max( l[i], mp[a[i] / j] );
35                 }
36             }
37             mp[a[i]] = i;
38         }
39         memset( mp, INF, sizeof(mp) );
40         for ( int i = n; i >= 1; i-- )
41         {
42             for ( int j = 1; j * j <= a[i]; j++ )
43             {
44                 if ( a[i] % j == 0 )
45                 {
46                     r[i] = min( r[i], mp[j] );
47                     r[i] = min( r[i], mp[a[i] / j] );
48                 }
49             }
50             mp[a[i]] = i;
51         }
52         int ans = 0;
53         for ( int i = 1; i <= n; i++ )
54         {
55             ans = ( ans + ( ll ) ( i - l[i] ) * ( r[i] - i ) ) % MOD;
56         }
57         printf("%d\n", ans);
58     }
59     return 0;
60 }

 

posted @ 2015-08-07 13:16  hxy_has_been_used  阅读(144)  评论(0编辑  收藏  举报