您的位置:首页 > 产品设计 > UI/UE

SPOJ 2916 Can you answer these queries V

2012-05-31 21:02 369 查看
SPOJ_2916

这个题目需要分情况讨论一下,如果y1<x2,那么就是前面区间的一个后缀,加上后面区间的一个前缀,再加上中间的部分,如果y1>=x2,则根据位置的不同又可以另分三种情况,逐一讨论并更新最优解即可。

分析之后就发现,在线段树的基础上写两个查询函数即可,一个就是和SPOJ_1716的GSS1那样功能的函数(在我的程序里面对应的是query这个函数),另一个是可以求一个区间最大的前缀和或者后缀和的函数(在我的程序里面对应的是Search这个函数)。

#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f3f
#define MAXD 10010
int N, A[MAXD], a[MAXD], mc[4 * MAXD], lc[4 * MAXD], rc[4 * MAXD];
int Max(int x, int y)
{
return x > y ? x : y;
}
void update(int cur, int x, int y)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
mc[cur] = Max(mc[ls], mc[rs]);
mc[cur] = Max(mc[cur], rc[ls] + lc[rs]);
lc[cur] = Max(lc[ls], A[mid] - A[x - 1] + lc[rs]);
rc[cur] = Max(rc[rs], A[y] - A[mid] + rc[ls]);
}
void build(int cur, int x, int y)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
if(x == y)
{
mc[cur] = lc[cur] = rc[cur] = a[x];
return ;
}
build(ls, x, mid);
build(rs, mid + 1, y);
update(cur, x, y);
}
int query(int cur, int x, int y, int s, int t, int flag, int &ans)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
if(x >= s && y <= t)
{
ans = Max(ans, mc[cur]);
if(flag == 0)
return lc[cur];
else
return rc[cur];
}
if(mid >= t)
return query(ls, x, mid, s, t, 0, ans);
else if(mid + 1 <= s)
return query(rs, mid + 1, y, s, t, 1, ans);
int ln, rn;
ln = query(ls, x, mid, s, t, 1, ans);
rn = query(rs, mid + 1, y, s, t, 0, ans);
ans = Max(ans, ln + rn);
if(flag == 0)
return Max(lc[ls], A[mid] - A[x - 1] + rn);
else
return Max(rc[rs], A[y] - A[mid] + ln);
}
void Search(int cur, int x, int y, int s, int t, int flag, int &ans)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = cur << 1 | 1;
if(x >= s && y <= t)
{
if(flag == 0)
ans = Max(ans, A[x - 1] - A[s - 1] + lc[cur]);
else
ans = Max(ans, A[t] - A[y] + rc[cur]);
return ;
}
if(mid >= s)
Search(ls, x, mid, s, t, flag, ans);
if(mid + 1 <= t)
Search(rs, mid + 1, y, s, t, flag, ans);
}
void init()
{
int i, j, k;
scanf("%d", &N);
A[0] = 0;
for(i = 1; i <= N; i ++)
{
scanf("%d", &a[i]);
A[i] = A[i - 1] + a[i];
}
build(1, 1, N);
}
void solve()
{
int i, q, ans, t1, t2, x1, y1, x2, y2;
scanf("%d", &q);
for(i = 0; i < q; i ++)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if(y1 < x2)
{
t1 = t2 = -INF;
Search(1, 1, N, x1, y1, 1, t1);
Search(1, 1, N, x2, y2, 0, t2);
printf("%d\n", t1 + t2 + A[x2 - 1] - A[y1]);
}
else
{
ans = -INF;
query(1, 1, N, x2, y1, 0, ans);
t1 = t2 = -INF;
Search(1, 1, N, x1, y1, 1, t1);
Search(1, 1, N, y1, y2, 0, t2);
ans = Max(ans, t1 + t2 - a[y1]);
t1 = t2 = -INF;
Search(1, 1, N, x1, x2, 1, t1);
Search(1, 1, N, x2, y2, 0, t2);
ans = Max(ans, t1 + t2 - a[x2]);
printf("%d\n", ans);
}
}
}
int main()
{
int t;
scanf("%d", &t);
while(t --)
{
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: