您的位置:首页 > 其它

HLG 1524 最大 (离散化线段树)

2014-06-05 18:20 162 查看
链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1524

Description

给包含n个数的初始序列,A[1], A[2], ..., A

给q多个操作,操作如下:
1 a b v, 把[a, b] 的值改为v,即A[a] = A[a+1] = ... = A = v。
2 a b, 查询[a, b] 之间的相同数的连续和最大值。

在[a, b]区间内,相同数的连续和最大值就是Sum(A[i], A[i+1], A[j]), a <= i <= j <= b,并且A[i] = A[i+1] = A[i+2] = A[i+3] = ... = A[j]。

[b]Input


有多组测试数据,不超过5组测试数据。
对于每组测试数据,第一个为 n (n<=10^5),第二行为n个数,每个数的范围[0, 1000]。
第三行为 q (q<=10^5),表示查询的次数。
接下来有q个操作,格式如下:
1 a b v, 把[a, b] 的值改为v,即A[a] = A[a+1] = ... = A = v。
2 a b, 查询[a, b] 之间的相同数的连续和最大值。
其中 1 <= a <= b <=n,0 <= v <= 1000.

[b]Output

每组测试数据先输出一行"Case id:",id从1开始计数。
对于每个查询,输出一行,包含一个整数,为相同数的连续和最大值。

Sample Input

5
2 2 1 2 3
3
2 1 4
1 1 3 2
2 1 5
7
120 985 727 979 68 558 732
4
1 2 5 627
2 2 7
2 4 5
1 5 7 571

Sample Output

Case 1:
4
8
Case 2:
2508
1254

代码如下: (这代码当时把我弄疯了)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <limits.h>
#include <algorithm>
#define maxn 100005
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;

int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; }

int lva[maxn<<4]; // 最左面的值
int lnu[maxn<<4]; // 最左面的数的个数
int rva[maxn<<4]; // 最右面的值
int rnu[maxn<<4]; // 最右面的数的个数
int mva[maxn<<4]; // 区间最大连续值
int add[maxn<<4]; // 延迟标记
int v[maxn], re[100005];

void creat(int l, int r, int rt)
{
add[rt] = -1;
if(l == r) {
lva[rt] = rva[rt] = v[l];
lnu[rt] = rnu[rt] = 1;
mva[rt] = v[l];
return;
}
int m = (l+r) >> 1;
creat(l, m, rt<<1);
creat(m+1, r, rt<<1|1);
lva[rt] = lva[rt<<1];
lnu[rt] = lnu[rt<<1];
rva[rt] = rva[rt<<1|1];
rnu[rt] = rnu[rt<<1|1];
if(lva[rt<<1]==lva[rt<<1|1] && lnu[rt<<1]==(m-l+1)) lnu[rt] += lnu[rt<<1|1];
if(rva[rt<<1]==rva[rt<<1|1] && rnu[rt<<1|1]==r-m) rnu[rt] += rnu[rt<<1];
mva[rt] = max(mva[rt<<1], mva[rt<<1|1]);
if(rva[rt<<1] == lva[rt<<1|1]) {
mva[rt] = max(mva[rt], rva[rt<<1]*rnu[rt<<1]+lva[rt<<1|1]*lnu[rt<<1|1]);
}
}

void update(int L, int R, int c, int l, int r, int rt)
{
if(L <= l && r <= R) {
add[rt] = c;
lva[rt] = rva[rt] = c;
lnu[rt] = rnu[rt] = r-l+1;
mva[rt] = c*(r-l+1);
return;
}
int m = (l+r) >> 1;
if(add[rt] != -1) {
add[rt<<1] = add[rt<<1|1] = add[rt];
lva[rt<<1] = rva[rt<<1] = lva[rt<<1|1] = rva[rt<<1|1] = add[rt];
lnu[rt<<1] = rnu[rt<<1] = m-l+1;
lnu[rt<<1|1] = rnu[rt<<1|1] = r - m;
mva[rt<<1] = (m-l+1) * add[rt];
mva[rt<<1|1] = (r-m) * add[rt];
add[rt] = -1;
}
if(L <= m) update(L, R, c, l, m, rt<<1);
if(R > m) update(L, R, c, m+1, r, rt<<1|1);
lva[rt] = lva[rt<<1];
lnu[rt] = lnu[rt<<1];
rva[rt] = rva[rt<<1|1];
rnu[rt] = rnu[rt<<1|1];
if(lva[rt<<1] == lva[rt<<1|1] && lnu[rt<<1] == (m-l+1)) lnu[rt] += lnu[rt<<1|1];
if(rva[rt<<1] == rva[rt<<1|1]&& rnu[rt<<1|1] == r-m) rnu[rt] += rnu[rt<<1];
mva[rt] = max(mva[rt<<1], mva[rt<<1|1]);
if(rva[rt<<1] == lva[rt<<1|1]) {
mva[rt] = max(mva[rt], rva[rt<<1]*rnu[rt<<1]+lva[rt<<1|1]*lnu[rt<<1|1]);
}
}

int query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R) return mva[rt];
int m = (l+r) >> 1;
if(add[rt] != -1) {
add[rt<<1] = add[rt<<1|1] = add[rt];
lva[rt<<1] = rva[rt<<1] = lva[rt<<1|1] = rva[rt<<1|1] = add[rt];
lnu[rt<<1] = rnu[rt<<1] = m-l+1;
lnu[rt<<1|1] = rnu[rt<<1|1] = r - m;
mva[rt<<1] = (m-l+1) * add[rt];
mva[rt<<1|1] = (r-m) * add[rt];
add[rt] = -1;
}
if(R <= m) return query(L, R, l, m, rt<<1);
else if(L > m) return query(L, R, m+1, r, rt<<1|1);
else {
int res = 0;
if(rva[rt<<1] == lva[rt<<1|1])
res = (min(rnu[rt<<1], m-L+1) + min(lnu[rt<<1|1], R-m)) * rva[rt<<1];
return max(res, max(query(L, m, l, m, rt<<1), query(m+1, R, m+1, r, rt<<1|1)));
}
}

int n, a, b, c, m, op, cas = 1, top = 0, tot;

void Init()
{
for(int i=1; i<=n; i++) scanf("%d", &v[i]);
creat(1, n, 1);
scanf("%d", &m);
tot = 0;
}

int main()
{
while(~scanf("%d", &n)) {
Init();
printf("Case %d:\n", cas++);
while(m--) {
scanf("%d", &op);
if(op == 1) {
scanf("%d %d %d", &a, &b, &c);
update(a, b, c, 1, n, 1);
}else {
scanf("%d %d", &a, &b);
printf("%d\n", query(a, b, 1, n, 1));
}
}
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  离散化线段树