您的位置:首页 > 其它

HDU 3954 Level up(线段树)

2012-07-22 13:26 429 查看
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int maxn = 10010;
int t, n, k, qw;
int need[11] = {0};
int maxexp[maxn<<2][11];
int add[maxn<<2];

void build(int l, int r, int rt)
{
for (int i = 1; i <= k; ++i)
maxexp[rt][i] = -1;
maxexp[rt][1] = 0;
add[rt] = 0;
if (l == r) return ;
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
}

void pushDown(int rt)
{
if (add[rt])
{
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
for (int i = 1; i <= k; ++i)
{
if (maxexp[rt<<1][i] != -1)
maxexp[rt<<1][i] += i * add[rt];
if (maxexp[rt<<1|1][i] != -1)
maxexp[rt<<1|1][i] += i * add[rt];
}
add[rt] = 0;
}
}

void pushUp(int rt)
{
for (int i = 1; i <= k; ++i)
{
maxexp[rt][i] = max(maxexp[rt<<1][i], maxexp[rt<<1|1][i]);
}
}

void levelUp(int l, int r, int rt)
{
if (l == r)
{
for (int i = 1; i < k; ++i)
{
if (maxexp[rt][i] != -1)
{
while (maxexp[rt][i] >= need[i+1] && i < k)
{
maxexp[rt][i+1] = maxexp[rt][i];
maxexp[rt][i] = -1;
i++;
}
break;
}
}
return ;
}
pushDown(rt);
int m = (l + r) >> 1;
for (int i = 1; i < k; ++i)
{
if (maxexp[rt<<1][i] >= need[i+1])
{
levelUp(l, m, rt << 1);
break;
}
}
for (int i = 1; i < k; ++i)
{
if (maxexp[rt<<1|1][i] >= need[i+1])
{
levelUp(m + 1, r, rt << 1 | 1);
break;
}
}
pushUp(rt);
}

void update(int l, int r, int L, int R, int e, int rt)
{
if (L <= l && R >= r)
{
add[rt] += e;
for (int i = 1; i <= k; ++i)
{
if (maxexp[rt][i] != -1)
{
maxexp[rt][i] += i * e;
}
}
for (int i = 1; i < k; ++i)
{
if (maxexp[rt][i] >= need[i+1])
{
levelUp(l, r, rt);
break;
}
}
return ;
}
if (l == r) return ;
pushDown(rt);
int m = (l + r) >> 1;
if (L <= m) update(l, m, L, R, e, rt << 1);
if (R > m) update(m + 1, r, L, R, e, rt << 1 | 1);
pushUp(rt);
}

int query(int l, int r, int L, int R, int rt)
{
if (L <= l && R >= r)
{
int ret = -1;
for (int i = 1; i <= k; ++i)
{
ret = max(ret, maxexp[rt][i]);
}
return ret;
}
pushDown(rt);
int m = (l + r) >> 1;
int ret = -1;
if (L <= m) ret = max(ret, query(l, m, L, R, rt << 1));
if (R > m) ret = max(ret, query(m + 1, r, L, R, rt << 1 | 1));
return ret;
}

int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d", &t);
for (int cas = 1; cas <= t; ++cas)
{
printf("Case %d:\n", cas);
scanf("%d%d%d", &n, &k, &qw);
for (int i = 2; i <= k; ++i)
{
scanf("%d", &need[i]);
}
char op[3];
int li, ri, ei;
build(1, n, 1);
for (int i = 0; i < qw; ++i)
{
scanf("%s", op);
if (op[0] == 'W')
{
scanf("%d%d%d", &li, &ri, &ei);
update(1, n, li, ri, ei, 1);
}
else
{
scanf("%d%d", &li, &ri);
printf("%d\n", query(1, n, li, ri, 1));
}
}
printf("\n");
}
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: