别问我为什么是指针也别问我为什么用了switch()(因为好玩)
单点修改+区间查询
#include
#include
#include
#include
using namespace std;
//Mystery_Sky
//线段树模板(单点修改+区间求和)
#define M 500050
#define Mid (l+r)>>1
struct Tree{
Tree *lc, *rc;
int x;
}dizhi[M<<1], *root = &dizhi[0];
int t = 1;
int a[M];
int n, m, k, x, y;
void build(Tree *tree, int l, int r)
{
if(l == r) {
tree->x = a[l];
return;
}
int mid = Mid;
tree->lc = &dizhi[++t];
tree->rc = &dizhi[++t];
build(tree->lc, l, mid);
build(tree->rc, mid+1, r);
tree->x = tree->lc->x + tree->rc->x;
}
void update(Tree *tree, int l, int r, int x, int d)
{
if(l == r) {
tree->x += d;
return;
}
int mid = Mid;
if(x <= mid) update(tree->lc, l, mid, x, d);
else update(tree->rc, mid+1, r, x, d);
tree->x = tree->lc->x + tree->rc->x;
}
int query(Tree *tree, int l, int r, int x, int y)
{
if(x <= l && y >= r) {
return tree->x;
}
int mid = Mid;
int ans = 0;
if(x <= mid) ans += query(tree->lc, l, mid, x, y);
if(y > mid) ans += query(tree->rc, mid+1, r, x, y);
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(root, 1, n);
for(int i = 1; i <= m; i++) {
scanf("%d%d%d", &k, &x, &y);
switch(k){
case 1:{
update(root, 1, n, x, y);
break;
}
case 2:{
printf("%d\n", query(root, 1, n, x, y));
break;
}
}
}
return 0;
}
区间修改+单点查询
#include
#include
#include
#include
using namespace std;
//Mystery_Sky
//线段树模板(区间修改+单点查询)
#define M 5000050
#define ll long long
#define INF 0x3f3f3f3f
#define Mid (l+r)>>1
struct Tree{
Tree *lc, *rc;
int x, lazy;
}dizhi[M<<1], *root = &dizhi[0];
int n, m, t=1;
int a[M];
int x, y, d, k;
void build(Tree *tree, int l, int r)
{
if(l == r) {
tree->x = a[l];
return;
}
int mid = Mid;
tree->lc = &dizhi[++t];
tree->rc = &dizhi[++t];
build(tree->lc, l, mid);
build(tree->rc, mid+1, r);
tree->x = tree->lc->x + tree->rc->x;
}
inline void pushdown(Tree *tree, int l, int r)
{
if(!tree->lazy) return;
int mid = Mid;
tree->lc->x += tree->lazy * (mid - l + 1);
tree->rc->x += tree->lazy * (r - mid);
tree->lc->lazy += tree->lazy;
tree->rc->lazy += tree->lazy;
tree->lazy = 0;
}
void update(Tree *tree, int l, int r, int x, int y, int d)
{
if(x <= l && y >= r) {
tree->x += d * (r - l + 1);
tree->lazy += d;
return;
}
pushdown(tree, l, r);
int mid = Mid;
if(x <= mid) update(tree->lc, l, mid, x, y, d);
if(y > mid) update(tree->rc, mid+1, r, x, y, d);
tree->x = tree->lc->x + tree->rc->x;
}
int query(Tree *tree, int l, int r, int x)
{
if(l == r) {
return tree->x;
}
pushdown(tree, l, r);
int mid = Mid;
if(x <= mid) return query(tree->lc, l, mid, x);
else return query(tree->rc, mid+1, r, x);
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(root, 1, n);
for(int i = 1; i <= m; i++) {
scanf("%d", &k);
switch(k) {
case 1:{
scanf("%d%d%d", &x, &y, &d);
update(root, 1, n, x, y, d);
break;
}
case 2:{
scanf("%d", &x);
printf("%d\n", query(root, 1, n, x));
break;
}
}
}
return 0;
}
区间修改+区间查询
#include
#include
#include
#include
using namespace std;
//Mystery_Sky
//线段树模板(区间修改+区间查询)
#define M 5000050
#define ll long long
#define INF 0x3f3f3f3f
#define Mid (l+r)>>1
struct Tree{
Tree *lc, *rc;
ll x, lazy;
}dizhi[M<<1], *root = &dizhi[0];
int n, m, t=1;
int a[M];
int x, y, d, k;
void build(Tree *tree, int l, int r)
{
if(l == r) {
tree->x = a[l];
return;
}
int mid = Mid;
tree->lc = &dizhi[++t];
tree->rc = &dizhi[++t];
build(tree->lc, l, mid);
build(tree->rc, mid+1, r);
tree->x = tree->lc->x + tree->rc->x;
}
inline void pushdown(Tree *tree, int l, int r)
{
if(!tree->lazy) return;
int mid = Mid;
tree->lc->x += tree->lazy * (mid - l + 1);
tree->rc->x += tree->lazy * (r - mid);
tree->lc->lazy += tree->lazy;
tree->rc->lazy += tree->lazy;
tree->lazy = 0;
}
void update(Tree *tree, int l, int r, int x, int y, int d)
{
if(x <= l && y >= r) {
tree->x += (ll) d * (r - l + 1);
tree->lazy += d;
return;
}
pushdown(tree, l, r);
int mid = Mid;
if(x <= mid) update(tree->lc, l, mid, x, y, d);
if(y > mid) update(tree->rc, mid+1, r, x, y, d);
tree->x = tree->lc->x + tree->rc->x;
}
ll query(Tree *tree, int l, int r, int x, int y)
{
if(x <= l && y >= r) {
return tree->x;
}
pushdown(tree, l, r);
int mid = Mid;
ll ans = 0;
if(x <= mid) ans += query(tree->lc, l, mid, x, y);
if(y > mid) ans += query(tree->rc, mid+1, r, x, y);
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(root, 1, n);
for(int i = 1; i <= m; i++) {
scanf("%d", &k);
switch(k) {
case 1:{
scanf("%d%d%d", &x, &y, &d);
update(root, 1, n, x, y, d);
break;
}
case 2:{
scanf("%d%d", &x, &y);
printf("%lld\n", query(root, 1, n, x, y));
break;
}
}
}
return 0;
}
区间乘+区间加+区间查询
留坑待补