@Dmaxiya
2020-08-25T00:41:34.000000Z
字数 4617
阅读 1002
Hello_World
线段树单点增减、区间求和裸题。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
#define LL long long
const int maxn = 50000 + 100;
int T, n, Index, tmp;
char str[10];
int sum[maxn << 2];
void push_up(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void build(int l, int r, int rt) {
if(l == r) {
scanf("%d", &sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
push_up(rt);
}
void add(int Index, int tmp, int l, int r, int rt) {
if(l == r) {
sum[rt] += tmp;
return ;
}
int m = (l + r) >> 1;
if(Index <= m) {
add(Index, tmp, l, m, rt << 1);
} else {
add(Index, tmp, m + 1, r, rt << 1 | 1);
}
push_up(rt);
}
int query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return sum[rt];
}
int m = (l + r) >> 1;
int ret = 0;
if(L <= m) {
ret += query(L, R, l, m, rt << 1);
}
if(m < R) {
ret += query(L, R, m + 1, r, rt << 1 | 1);
}
return ret;
}
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(false);
scanf("%d", &T);
for(int cas = 1; cas <= T; ++cas) {
printf("Case %d:\n", cas);
scanf("%d", &n);
build(1, n, 1);
while(scanf("%s", str), str[0] != 'E') {
scanf("%d%d", &Index, &tmp);
if(str[0] == 'Q') {
printf("%d\n", query(Index, tmp, 1, n, 1));
} else if(str[0] == 'A') {
add(Index, tmp, 1, n, 1);
} else {
add(Index, -tmp, 1, n, 1);
}
}
}
return 0;
}
在 游戏中,有一种肉勾,这种肉勾可以由等长度的、不同材质的长棒组成,分别有金、银、铜三种材料,铜的价值为 ,银的价值为 ,金的价值为 ,现在有 组数据,每组数据的肉勾总共有 段长棒, 次操作,每次操作将区间 上的所有长棒材料换为指定材料,问最后长棒的价值。
线段树区间更新、区间求和裸题。由于最后只对整段区间求和查询,所以直接输出 就行,不用 函数。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
#define LL long long
const int maxn = 100000 + 100;
int T, n, q, l, r, num;
int sum[maxn << 2], lazy[maxn << 2];
void push_up(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void push_down(int rt, int len) {
if(lazy[rt] != 0) {
lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
sum[rt << 1] = (len - (len >> 1)) * lazy[rt];
sum[rt << 1 | 1] = (len >> 1) * lazy[rt];
lazy[rt] = 0;
}
}
void build(int l, int r, int rt) {
lazy[rt] = 0;
if(l == r) {
sum[rt] = 1;
return ;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
push_up(rt);
}
void update(int L, int R, int tmp, int l, int r, int rt) {
if(L <= l && r <= R) {
lazy[rt] = tmp;
sum[rt] = (r - l + 1) * tmp;
return ;
}
push_down(rt, r - l + 1);
int m = (l + r) >> 1;
if(L <= m) {
update(L, R, tmp, l, m, rt << 1);
}
if(m < R) {
update(L, R, tmp, m + 1, r, rt << 1 | 1);
}
push_up(rt);
}
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(false);
scanf("%d", &T);
for(int cas = 1; cas <= T; ++cas) {
scanf("%d", &n);
build(1, n, 1);
scanf("%d", &q);
for(int i = 0; i < q; ++i) {
scanf("%d%d%d", &l, &r, &num);
update(l, r, num, 1, n, 1);
}
printf("Case %d: The total value of the hook is %d.\n", cas, sum[1]);
}
return 0;
}
对于给定的 个数据 ,有 次操作,第一种操作为将区间 上的数字都加上 ,第二种操作为求区间 上的所有数字的和。
线段树区间增减、区间求和裸题。注意 。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
#define LL long long
const int maxn = 100000 + 100;
int n, q, a, b, c;
char ch[2];
LL sum[maxn << 2], lazy[maxn << 2];
void push_up(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void push_down(int rt, int len) {
if(lazy[rt] != 0) {
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
sum[rt << 1] += (len - (len >> 1)) * lazy[rt];
sum[rt << 1 | 1] += (len >> 1) * lazy[rt];
lazy[rt] = 0;
}
}
void build(int l, int r, int rt) {
lazy[rt] = 0;
if(l == r) {
scanf("%lld", &sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
push_up(rt);
}
void add(int L, int R, int tmp, int l, int r, int rt) {
if(L <= l && r <= R) {
lazy[rt] += tmp;
sum[rt] += (r - l + 1) * tmp;
return ;
}
push_down(rt, r - l + 1);
int m = (l + r) >> 1;
if(L <= m) {
add(L, R, tmp, l, m, rt << 1);
}
if(R > m) {
add(L, R, tmp, m + 1, r, rt << 1 | 1);
}
push_up(rt);
}
LL query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return sum[rt];
}
push_down(rt, r - l + 1);
int m = (l + r) >> 1;
LL ret = 0;
if(L <= m) {
ret += query(L, R, l, m, rt << 1);
}
if(m < R) {
ret += query(L, R, m + 1, r, rt << 1 | 1);
}
return ret;
}
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // LOCAL
ios::sync_with_stdio(false);
while(scanf("%d%d", &n, &q) != EOF) {
build(1, n, 1);
while(q--) {
scanf("%s", ch);
if(ch[0] == 'Q') {
scanf("%d%d", &a, &b);
printf("%lld\n", query(a, b, 1, n, 1));
} else {
scanf("%d%d%d", &a, &b, &c);
add(a, b, c, 1, n, 1);
}
}
}
return 0;
}