uva 12501 Bulky process of bulk reduction

本文从WordPress迁移而来, 查看全部WordPress迁移文章

【UVA提交失败,至今还没有评判】

线段树 区间更新 区间求和(有点特殊)

题意:给出长度为n的区间,一开始每个单元的权值为100,有查询和修改操作。修改操作时一个区间内每个单元的权值都加上一个D;查询操作时查询一个区间内的和,不过不是简单相加,而是每个单元附一个权值:

查询[L,R]权值和 = 1 v[L] + 2 v[L+1] + 3 v[L+2] + …….. + (L+R) v[R]

对于查询我是这样做的,将要查询的区间分成多段,每一段内,该段里面的每个单元的权值是相同的,那么该段的权值和就可以直接算出,例如

[5,15], [5,7]每个单元的权值都是100,[8,13]每个单元的权值都是200,[14,15]每个单元的权值都是150

那么整个区间的和 = (1+2+3) 100 + (4+5+6+7+8+9) 20 + (10+11) * 150,这样就只计算了3次

因为最悲剧的情况就是整个区间内每个单元的权值都是不同的,那么相当于一个一个单元累加起来

可惜UVA还不能提交不知道是否能通过,先做一个记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define N 100010
#define LL long long
#define cl(xx,yy) memset((xx),(yy),sizeof((xx)))
#define lson(i) ((i)<<1)
#define rson(i) ((i)<<1|1)

int n;
struct SegTree{
int l,r;
LL lazy,val;
SegTree(){}
SegTree(int _l,int _r){
l = _l; r = _r; lazy = 0; val = 100;
}
int mid(){
return (l+r)>>1;
}
int callen(){
return r - l + 1;
}
}t[N<<2];

void build(int rt,int a,int b){
t[rt] = SegTree(a,b);
if(a == b) return ;
int mid = t[rt].mid();
build(lson(rt),a,mid);
build(rson(rt),mid+1,b);
}

void PushDown(int rt){
if(t[rt].lazy == -1) return ;
t[lson(rt)].lazy = t[rson(rt)].lazy = t[rt].lazy;
t[rt].lazy = -1;
}

LL query(int rt,int a,int b,int x,int y){
if(t[rt].lazy != -1){
return (t[rt].val+t[rt].lazy) * ((x+y)*(y-x+1)/2);
}
PushDown(rt);
int mid = t[rt].mid();
if(b <= mid)
return query(lson(rt),a,b,x,y);
else if(a > mid)
return query(rson(rt),a,b,x,y);
else{
int m = x + mid - a;
LL res1 = query(lson(rt),a,b,x,m);
LL res2 = query(rson(rt),a,b,m+1,y);
return res1 + res2;
}
}

void updata(int rt,int a,int b,int x){
if(t[rt].l == a && t[rt].r == b){
t[rt].lazy = x;
return ;
}
PushDown(rt);
int mid = t[rt].mid();
if(b <= mid)
updata(lson(rt),a,b,x);
else if(a > mid)
updata(rson(rt),a,b,x);
else{
updata(lson(rt),a,mid,x);
updata(rson(rt),mid+1,b,x);
}
}

int main(){
int T,q;
scanf("%d",&T);
for(int cas = 1; cas <= T; cas++){
scanf("%d%d",&n,&q);
printf("Case %d:",cas);
build(1,1,n);
while(q--){
char op[10];
scanf("%s",op);
if(op[0] == 'q'){
int a,b;
scanf("%d%d",&a,&b);
LL res = query(1,a,b,1,(b-a+1));
printf("%lld\n",res);
}
else{
int a,b,x;
scanf("%d%d%d",&a,&b,&x);
updata(1,a,b,x);
}
}
}
return 0;
}