HDU - 1166 敌兵布阵
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
点更新,区间查询
区间和,直接代模板
代码如下:
#include <stdio.h>
#include <math.h>
#define MAXN 50005
int a[MAXN];
int segment_tree[MAXN * 4];
void build_tree(int x, int l, int r) {
if (l == r) {
segment_tree[x] = a[l];
return;
}
int mid = (l + r) >> 1;
build_tree(x * 2, l, mid);
build_tree(x * 2 + 1, mid + 1, r);
segment_tree[x] = segment_tree[x * 2] + segment_tree[x * 2 + 1];
}
void update_tree(int x, int l, int r, int t, int val) {
segment_tree[x] += val;
if (segment_tree[x] < 0)
segment_tree[x] = 0;
if (l == t && r == t)
return;
int mid = (l + r) >> 1;
if (mid >= t)
update_tree(x * 2, l, mid, t, val);
else
update_tree(x * 2 + 1, mid + 1, r, t, val);
}
int query_tree(int x, int l, int r, int start, int end) {
if (l == start && r == end)
return segment_tree[x];
int mid = (l + r) >> 1;
if (end <= mid)
return query_tree(x * 2, l, mid, start, end);
else if (start > mid)
return query_tree(x * 2 + 1, mid + 1, r, start, end);
else
return query_tree(x * 2, l, mid, start, mid) + query_tree(x * 2 + 1, mid + 1, r, mid + 1, end);
}
int main() {
int cas, n, val1, val2;
char command[10];
scanf("%d", &cas);
for (int t = 1; t <= cas; t++) {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", a + i);
build_tree(1, 1, n);
printf("Case %d:\n", t);
while (scanf("%s", command) && command[0] != 'E') {
scanf("%d%d", &val1, &val2);
if (command[0] == 'A')
update_tree(1, 1, n, val1, val2);
else if (command[0] == 'S')
update_tree(1, 1, n, val1, -val2);
else
printf("%d\n", query_tree(1, 1, n, val1, val2));
}
}
}
HDU - 1754 I Hate It
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
点更新,区间查询
区间最大,直接代模板
代码如下:
#include <stdio.h>
#include <math.h>
#define MAXN 200005
int a[MAXN];
int segment_tree[MAXN * 4];
int max_val(int x, int y) {
if (x < y) return y;
else return x;
}
void build_tree(int x, int l, int r) {
if (l == r) {
segment_tree[x] = a[l];
return;
}
int mid = (l + r) >> 1;
build_tree(x * 2, l, mid);
build_tree(x * 2 + 1, mid + 1, r);
segment_tree[x] = max_val(segment_tree[x * 2], segment_tree[x * 2 + 1]);
}
void update_tree(int x, int l, int r, int t, int val) {
if (segment_tree[x] < val)
segment_tree[x] = val;
if (l == t && r == t) {
segment_tree[x] = val;
return;
}
int mid = (l + r) >> 1;
if (mid >= t)
update_tree(x * 2, l, mid, t, val);
else
update_tree(x * 2 + 1, mid + 1, r, t, val);
}
int query_tree(int x, int l, int r, int start, int end) {
if (l == start && r == end)
return segment_tree[x];
int mid = (l + r) >> 1;
if (mid >= end)
return query_tree(x * 2, l, mid, start, end);
else if (mid < start)
return query_tree(x * 2 + 1, mid + 1, r, start, end);
else
return max_val(query_tree(x * 2, l, mid, start, mid),
query_tree(x * 2 + 1, mid + 1, r, mid + 1, end));
}
int main() {
int n, m, val1, val2;
char command;
while (scanf("%d%d", &n, &m) != EOF) {
for (int i = 1; i <= n; i++)
scanf("%d", a + i);
build_tree(1, 1, n);
while (m--) {
scanf(" %c%d%d", &command, &val1, &val2);
if (command == 'U')
update_tree(1, 1, n, val1, val2);
else
printf("%d\n", query_tree(1, 1, n, val1, val2));
}
}
}
POJ - 3468 A Simple Problem With Intergers
题目链接:http://poj.org/problem?id=3468
区间更新,区间查询
添加标记数组,每次访问子区间时,重新计算标记数组
记得以前训练时,每次碰到区间更新的线段树就跪,现在哪怕许久没碰这些东西,随便就写出来了,时间是捧猪饲料
设置四倍空间会RE,有点看不懂,懒了懒了
代码如下:
#include <stdio.h>
#include <math.h>
#define MAXN 100005
#define int_64 long long
int_64 a[MAXN];
int_64 segment_tree[MAXN * 6];
int_64 segment_lazy[MAXN * 6];
void build_tree(int x, int l, int r) {
if (l == r) {
segment_tree[x] = a[l];
segment_lazy[x] = 0;
return;
}
int mid = (l + r) >> 1;
build_tree(x * 2, l, mid);
build_tree(x * 2 + 1, mid + 1, r);
segment_tree[x] = segment_tree[x * 2] + segment_tree[x * 2 + 1];
}
void update_tree(int x, int l, int r, int start, int end, int_64 val) {
int mid = (l + r) >> 1;
if (segment_lazy[x]) {
segment_tree[x * 2] += segment_lazy[x] * (mid - l + 1);
segment_tree[x * 2 + 1] += segment_lazy[x] * (r - mid);
segment_lazy[x * 2] += segment_lazy[x];
segment_lazy[x * 2 + 1] += segment_lazy[x];
segment_lazy[x] = 0;
}
if (l == start && r == end) {
segment_lazy[x] = val;
segment_tree[x] += val * (end - start + 1);
return;
}
if (mid >= end) {
update_tree(x * 2, l, mid, start, end, val);
}
else if (mid < start) {
update_tree(x * 2 + 1, mid + 1, r, start, end, val);
}
else {
update_tree(x * 2, l, mid, start, mid, val);
update_tree(x * 2 + 1, mid + 1, r, mid + 1, end, val);
}
segment_tree[x] = segment_tree[x * 2] + segment_tree[x * 2 + 1];
}
int_64 query_tree(int x, int l, int r, int start, int end) {
int mid = (l + r) >> 1;
if (segment_lazy[x]) {
segment_tree[x * 2] += segment_lazy[x] * (mid - l + 1);
segment_tree[x * 2 + 1] += segment_lazy[x] * (r - mid);
segment_lazy[x * 2] += segment_lazy[x];
segment_lazy[x * 2 + 1] += segment_lazy[x];
segment_lazy[x] = 0;
}
if (l == start && r == end)
return segment_tree[x];
if (mid >= end)
return query_tree(x * 2, l, mid, start, end);
else if (mid < start)
return query_tree(x * 2 + 1, mid + 1, r, start, end);
else
return query_tree(x * 2, l, mid, start, mid) +
query_tree(x * 2 + 1, mid + 1, r, mid + 1, end);
}
int main() {
int n, m, val1, val2;
int_64 val3;
char command;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
scanf("%lld", a + i);
build_tree(1, 1, n);
while (m--) {
scanf(" %c%d%d", &command, &val1, &val2);
if (command == 'Q') {
printf("%lld\n", query_tree(1, 1, n, val1, val2));
}
else {
scanf("%lld", &val3);
update_tree(1, 1, n, val1, val2, val3);
}
}
}
POJ - 2528 Mayor’s Posters
题目链接:http://poj.org/problem?id=2528
离散化,区间更新
区间范围较大,而端点相对稀疏,因此可以重新定义区间
好久不用STL,排序写到一半才想起来
代码如下:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#define MAXN 20005
#define MAXT 10000005
int segment_tree[MAXN * 6];
int initial_data[MAXN];
int initial_sort[MAXN];
int hash_table[MAXT];
bool visible[MAXN / 2];
void build_tree() {
memset(visible, false, sizeof(visible));
memset(segment_tree, 0, sizeof(segment_tree));
}
void update_tree(int x, int l, int r, int start, int end, int val) {
if (segment_tree[x]) {
segment_tree[x * 2] = segment_tree[x * 2 + 1] = segment_tree[x];
segment_tree[x] = 0;
}
if (l == start && r == end) {
segment_tree[x] = val;
return;
}
int mid = (l + r) >> 1;
if (mid >= end) {
update_tree(x * 2, l, mid, start, end, val);
}
else if (mid < start) {
update_tree(x * 2 + 1, mid + 1, r, start, end, val);
}
else {
update_tree(x * 2, l, mid, start, mid, val);
update_tree(x * 2 + 1, mid + 1, r, mid + 1, end, val);
}
if (segment_tree[x * 2] && segment_tree[x * 2] == segment_tree[x * 2 + 1])
segment_tree[x] = segment_tree[x * 2];
}
int total_num = 0;
void query_tree(int x, int l, int r) {
if (segment_tree[x] || l == r) {
if (!visible[segment_tree[x]]) {
visible[segment_tree[x]] = true;
total_num++;
}
return;
}
int mid = (l + r) >> 1;
query_tree(x * 2, l, mid);
query_tree(x * 2 + 1, mid + 1, r);
}
int n;
int main() {
int cas, n, cur_interval;
scanf("%d", &cas);
while (cas--) {
build_tree();
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", initial_data + 2 * i, initial_data + 2 * i + 1);
initial_sort[2 * i] = initial_data[2 * i];
initial_sort[2 * i + 1] = initial_data[2 * i + 1];
}
std::sort(initial_sort, initial_sort + 2 * n);
cur_interval = std::unique(initial_sort, initial_sort + 2 * n) - initial_sort;
for (int i = 0; i < cur_interval; i++)
hash_table[initial_sort[i]] = i + 1;
for (int i = 0; i < n; i++)
update_tree(1, 1, cur_interval, hash_table[initial_data[2 * i]], hash_table[initial_data[2 * i + 1]], i + 1);
total_num = 0;
visible[0] = true;
query_tree(1, 1, cur_interval);
printf("%d\n", total_num);
}
}
HDU - 1698 Just A Hook
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698
区间更新,查询
没什么新意,模板
代码如下:
#include <stdio.h>
#include <math.h>
#define MAXN 100005
int segment_tree[MAXN * 6];
int segment_lazy[MAXN * 6];
void build_tree(int x, int l, int r) {
segment_lazy[x] = 0;
if (l == r) {
segment_tree[x] = 1;
return;
}
int mid = (l + r) >> 1;
build_tree(x * 2, l, mid);
build_tree(x * 2 + 1, mid + 1, r);
segment_tree[x] = segment_tree[x * 2] + segment_tree[x * 2 + 1];
}
void update_tree(int x, int l, int r, int start, int end, int val) {
if (l == start && r == end) {
segment_lazy[x] = val;
segment_tree[x] = (r - l + 1) * val;
return;
}
int mid = (l + r) >> 1;
if (segment_lazy[x]) {
segment_tree[x * 2] = (mid - l + 1) * segment_lazy[x];
segment_tree[x * 2 + 1] = (r - mid) * segment_lazy[x];
segment_lazy[x * 2] = segment_lazy[x * 2 + 1] = segment_lazy[x];
segment_lazy[x] = 0;
}
if (mid >= end) {
update_tree(x * 2, l, mid, start, end, val);
}
else if (mid < start) {
update_tree(x * 2 + 1, mid + 1, r, start, end, val);
}
else {
update_tree(x * 2, l, mid, start, mid, val);
update_tree(x * 2 + 1, mid + 1, r, mid + 1, end, val);
}
segment_tree[x] = segment_tree[x * 2] + segment_tree[x * 2 + 1];
}
void query_tree(int x, int l, int r) {
if (segment_lazy[x]) {
segment_tree[x] = (r - l + 1) * segment_lazy[x];
segment_lazy[x] = 0;
return;
}
if (l == r) {
return;
}
int mid = (l + r) >> 1;
query_tree(x * 2, l, mid);
query_tree(x * 2 + 1, mid + 1, r);
segment_tree[x] = segment_tree[x * 2] + segment_tree[x * 2 + 1];
}
int main() {
int cas, n, m;
scanf("%d", &cas);
int start, end, val;
for (int t = 1; t <= cas; t++) {
scanf("%d%d", &n, &m);
build_tree(1, 1, n);
while (m--) {
scanf("%d%d%d", &start, &end, &val);
update_tree(1, 1, n, start, end, val);
}
query_tree(1, 1, n);
printf("Case %d: The total value of the hook is %d.\n", t, segment_tree[1]);
}
}