Hdu 5358 First One (尺取法+枚举)

题目链接:

  Hdu 5358 First One

题目描述:

  数组a有n个元素,S[i,j]定义为a[i]+a[i+1]+.....+a[j],问:这个死东西等于多少?

解题思路:

  二分肯定超,这个题目的时间卡的炒鸡严格,只有n*log(n)的复杂度才能过,n*log(n)^2都不可以的。

  只需要枚举K,并且枚举区间左端i值,计算K的贡献值,然后遍历时候计算一下常数相加即可。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const LL maxn = 100005;
 8 LL dp[maxn][35], arr[maxn];
 9 int main ()
10 {
11     int t, n;
12     scanf ("%d", &t);
13     while (t --)
14     {
15         scanf ("%d", &n);
16         arr[0] = 0;
17         for (int i=1; i<=n; i++)
18             scanf ("%lld", &arr[i]);
19         for (int i=0; i<35; i++)
20         {
21             LL sum = 1LL<<(i+1);
22             LL num = arr[1];
23             LL p = 1;
24             for (int j=1; j<=n; j++)
25             {
26                 num -= arr[j-1];
27                 while (num<sum && p<=n)
28                     num += arr[++p];
29                 dp[j][i] = p;//S[j,p]<2^i
30             }
31         }
32         LL ans = 0, res;
33         for (int i=1; i<=n; i++)
34         {
35             LL p = i, q;
36             for (int j=0; j<35; j++)
37             {
38                 q = dp[i][j];
39                 res = (j+1)*(i*(q-p) + (q+p-1)*(q-p)/2);
40                 ans += res;
41                 p = q;
42             }
43         }
44         printf ("%lld\n", ans);
45     }
46     return 0;
47 }

 对了,大家看了我的题解如果还是TLE的话,希望大家不要留言骂我哦。因为编译环境不同,HDU就会返回不同的答案,什么为什么,我也不知道啦。

posted @ 2015-08-07 14:26  罗茜  阅读(248)  评论(0编辑  收藏  举报