HDU _1698_区间修改+思维
背景:在一段区间内将数组所有值改变为另一值.延迟标记
- 延迟标记还可以用在 将区间内数组所有的值增加或者减少一个值
建个空线段树
更新所有的延迟标记为1
change()
的原理是:找到所有唯一的一个区间在线段树上的点.然后标记查询要递归遍历到所有的节点
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#include <iostream>
using namespace std;
const int maxn = 1e5+5;
struct segementTree {
int left,right;
int add,sum;
#define left(i) tree[i].left
#define right(i) tree[i].right
#define add(i) tree[i].add
#define sum(i) tree[i].sum
} tree[maxn*4];
void build(int p,int left,int right) {
left(p) = left; right(p) = right;
if (left == right) return ;
int mid = (left(p) + right(p))/2;
build(2*p,left,mid);
build(2*p+1,mid+1,right);
}
void pushDown(int p) {
if (add(p)) {
add(2*p) = add(p);
add(2*p+1) = add(p);
add(p) = 0;
}
}
void change(int p,int left,int right,int val) {
if (left(p)==left && right(p)==right) {
add(p) = val;
return ;
}
pushDown(p);
int mid = (left(p)+right(p))/2;
if (right <= mid) change(p*2,left,right,val);
else if (left > mid) change(2*p+1,left,right,val);
else {
change(p*2,left,mid,val);
change(p*2+1,mid+1,right,val);
}
}
int ans = 0;
void query(int p,int left,int right) {
if (add(p)) {
ans += add(p) * (right - left + 1);
return ;
}
if (left == right) return ;
int mid = (left(p) + right(p))/2;
query(2*p,left,mid);
query(2*p+1,mid+1,right);
return ;
}
int main() {
// freopen("a.txt","r",stdin);
int times; cin>>times;
int n,m,u,v,w,cnt=0;
while (times--) {
ans = 0;
scanf("%d%d",&n,&m);
build(1,1,n);
change(1,1,n,1);
for (int i=1; i<=m; i++) {
scanf("%d%d%d",&u,&v,&w);
change(1,u,v,w);
}
query(1,1,n);
printf("Case %d: The total value of the hook is %d.\n",++cnt,ans);
}
return 0;
}思维:
存读入.然后遍历每一个点.
从后往前找到倒数第一个值就退出,加起来
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!