| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
水题,线段树水过。考虑到题目给的内存有点小,开一颗线段树重复利用,每次得到的值用另一数组记录一下即可,这样就能转化成区间最大问题了。不懂看代码!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
inline int Read(){
int e = 0; char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while('0' <= ch && ch <= '9') e = e*10 + (ch-'0'), ch = getchar();
return e;
}
const int maxn = 1e5 + 7;
int tree[maxn<<2], k[maxn], s[maxn];
inline int max(int u, int v){
return u>v? u: v;
}
void Buildtree(int l, int r, int key){
if(l == r){
tree[key] = k[l];
return;
}
int mid = (l + r) >> 1;
Buildtree(l, mid, key<<1);
Buildtree(mid+1, r, key<<1|1);
tree[key] = max(tree[key<<1], tree[key<<1|1]);
}
int Query(int l, int r, int ls, int rs, int key){
if(ls <= l && r <= rs) return tree[key];
int mid = (l + r) >> 1, ans = 0;
if(ls <= mid) ans = max(ans, Query(l, mid, ls, rs, key<<1));
if(mid < rs) ans = max(ans, Query(mid+1, r, ls, rs, key<<1|1));
return ans;
}
int main(){
int t = Read(), n, len;
while(t --){
n = Read();
for(int i = 1; i <= n; i ++) k[i] = Read();
len = Read();
for(int i = 1; i <= n; i ++){
k[i] += k[i-1];
s[i] = k[i] - k[max(i-len, 0)];
}
for(int i = 1; i <= n; i ++) k[i] = s[i];
Buildtree(1, n, 1);
for(int i = len+1; i <= n; i ++) k[i] = Query(1, n, 1, i-len, 1) + s[i];
Buildtree(1, n, 1);
int ans = 0;
for(int i = 2*len+1; i <= n; i ++){
k[i] = Query(1, n, 1, i-len, 1) + s[i];
ans = max(k[i], ans);
}
printf("%d\n", ans);
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator