回归的第一天就听大姐姐的LCT
发现还要先懂WT大哥哥的SPLAY
发现还要先复习一下线段树
发现要复习一下二叉树
发现......
好吧其实没这么多发现
总之线段树又打了一遍
线段树
一、建树
二、查询
三、点修改
四、区间修改
(还要注意一个lazy-tag,还是迷迷糊糊的)
自己好好理解吧~
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
//eg.找最小数
using namespace std;
#define maxn (1000+10)
#define INF 0x7f7f7f7f
int a[maxn];
struct node{
int val;
int lazy;
}seg[maxn*4];
void built(int node, int be, int en){
seg[node].lazy = 0;
if(be == en) seg[node].val = a[be];
else{
int mid = be+((en-be)>>1);
built(node*2, be, mid);
built(node*2+1, mid+1, en);
seg[node].val = min(seg[node*2].val, seg[node*2+1].val);
}
}
void update_point(int node, int be, int en, int ind, int add){
if(be == en && ind == be){
seg[node].val += add;
return;
}
int mid = be+((en-be)>>1);
if(ind <= mid)update_point(node*2, be, mid, ind, add);
else update_point(node*2+1, mid+1, en, ind, add);
seg[node].val = min(seg[node*2].val, seg[node*2+1].val);
}
void pushdown(int node){
if(seg[node].lazy != 0){
seg[node*2].lazy += seg[node].lazy;
seg[node*2+1].lazy += seg[node].lazy;
seg[node*2].val += seg[node].lazy;
seg[node*2+1].val += seg[node].lazy;
seg[node].lazy = 0;
}
}
int query(int node, int be, int en, int le, int ri){
if(be > ri || en < le) return INF;
if(be >= le && en <= ri) return seg[node].val;
pushdown(node);
int mid = be+((en-be)>>1);
return min(query(node*2, be, mid, le, ri),
query(node*2+1, mid+1, en, le, ri));
}
void update_interval(int node, int be, int en, int le, int ri, int add){
if(be > ri || en < le) return;
if(be >= le && en <= ri){
seg[node].lazy += add;
seg[node].val += add;
return;
}
pushdown(node);
int mid = be+((en-be)>>1);
update_interval(node*2, be, mid, le, ri, add);
update_interval(node*2+1, mid+1, en, le, ri, add);
seg[node].val = min(seg[node*2].val, seg[node*2+1].val);
}
int main(){
freopen("segtree.in", "r", stdin);
freopen("segtree.out","w",stdout);
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
built(1, 1, n);
int p, q, ans = 0;
scanf("%d", &p);
for(int i = 1; i <= p; i++){
scanf("%d", &q);
int x, y, z;
if(!q){
scanf("%d%d", &x, &y);
ans = query(1, 1, n, x, y);
printf("%d\n", ans);
}
else if(q == 1){//point update
scanf("%d%d", &x, &y);
update_point(1, 1, n, x, y);
}
else if(q == 2){//interval update
scanf("%d%d%d", &x, &y, &z);
update_interval(1, 1, n, x, y, z);
}
}
return 0;
}