题目链接:防守阵地 I
好不容易推出公式,义无反顾的用线段树区间求和,然后MLE。
get区间求和新技能。【技能好熟悉....】
然后。知道公式and get新技能的情况下,卡了快一个点,原因是,那个很讨厌的sum,如果I==1的话,就不能直接那样求了。特判一下。然后!每次求得新ans的基础都是上一个ans,而不是之前的最大的ans,蠢蠢的求了一晚上最大还不知所谓,甚至一开始换成preans的时候也是max。蠢哭。
感受,生平最恨抖机灵,weisenme...因为woruo吧....
附代码:
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; #define maxn 1000010 int num[maxn]; // 储存每个士兵的能量值 int sum[maxn]; // sum[i] 表示前i个士兵的能量值之和 /* 公式: ans[i] 表示以i开头的m个士兵的能量值的话 ans[i] = ans[i-1] - sum(a[i-1], a[i-1 + m - 1]) + a[i+m-1]*m; */ int main() { int n, m; while(~scanf("%d%d", &n, &m)) { memset(sum, 0, sizeof(sum)); for (int i=0; i<n; ++i) { scanf("%d", &num[i]); sum[i+1] = sum[i] + num[i]; } int ans = 0; for (int i=0; i<m; ++i) { ans += num[i] * (i+1); } int preans = ans; for (int i=1; i+m-1<n; ++i) { // cout << preans << "+++++=\n"; if (i == 1) { preans = preans-sum[m] + m*num[i+m-1]; } else { preans = preans-(sum[i+m-1]-sum[i-1])+m*num[i+m-1]; // sum[i-2]好头疼............. } ans = max(ans, preans); } printf("%d\n", ans); } return 0; }