线段树的模版题,求区间最值和修改一个值,用Splaytree来写更简单!
伸展树code:
#include
#include
using namespace std;
#define lson x->ch[0]
#define rson x->ch[1]
#define ket (root->ch[1]->ch[0])
const int maxn = 222222 + 10;
struct NODE {
NODE *pre, *ch[2];
int val, mx, id, sz;
void up() {
sz = ch[0]->sz + ch[1]->sz + 1;
mx = val;
if(ch[0]->pre) mx = max(mx, ch[0]->mx);
if(ch[1]->pre) mx = max(mx, ch[1]->mx);
}
};
struct Splaytree {
int top;
NODE node[maxn], *null, *root;
void Rotate(NODE *x, int c) {
NODE *y = x->pre;
y->ch[!c] = x->ch[c];
if(x->ch[c] != null) x->ch[c]->pre = y;
x->pre = y->pre;
if(y->pre != null) y->pre->ch[ y->pre->ch[1]==y ] = x;
x->ch[c] = y; y->pre = x;
y->up();
}
void Splay(NODE *x, NODE *go) {
while(x->pre != go) {
if(x->pre->pre == go) Rotate(x, x->pre->ch[0]==x);
else {
NODE *y = x->pre, *z = y->pre;
int f = z->ch[1] == y;
if(y->ch[f] == x) Rotate(y, !f);
else Rotate(x, f);
Rotate(x, !f);
}
}
x->up();
if(go == null) root = x;
}
void RTO(int k, NODE *go) {
NODE *x = root;
while(lson->sz != k) {
if(lson->sz > k) x = lson;
else {
k -= lson->sz + 1;
x = rson;
}
}
Splay(x, go);
}
int a[maxn];
NODE *newnode(int c, NODE *f) {
NODE *x = &node[++top];
x->pre = f; x->id = top;
x->val = x->mx = c;
x->sz = 1;
lson = rson = null;
return x;
}
NODE *build(int l, int r, NODE *f) {
if(l > r) return null;
int mid = (l+r)/2;
NODE *x = newnode(a[mid], f);
lson = build(l, mid-1, x);
rson = build(mid+1, r, x);
x->up();
return x;
}
void init(int n) {
null = &node[0];
null->sz = null->id = null->val = null->mx = 0;
top = 0;
root = newnode(-1, null);
root->ch[1] = newnode(-1, root);
ket = build(0, n-1, root->ch[1]);
root->ch[1]->up(); root->up();
}
void query(int l, int r) {
if(l > r) swap(l, r);
RTO(l-1, null);
RTO(r+1, root);
printf("%d\n", ket->mx);
}
void update(int x, int y) {
RTO(x, null);
root->val = y;
}
void solve() {
int n, m;
while(scanf("%d%d", &n, &m) != -1) {
for(int i = 0;i < n; i++) scanf("%d", &a[i]);
init(n);
while(m--) {
char op[2]; int x, y;
scanf("%s%d%d", op, &x, &y);
if(op[0] == 'Q') query(x, y);
else update(x, y);
}
}
}
}spt;
int main() {
spt.solve();
return 0;
}
线段树code:
#include
#include
using namespace std;
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
const int maxn = 200000+5;
struct Segtree {
int mx[maxn<<2];
void build(int rt, int l, int r) {
if(l == r) {
scanf("%d", &mx[rt]);
return ;
}
int mid = (l+r)/2;
build(lson); build(rson);
up(rt);
}
void up(int rt) {
mx[rt] = max(mx[rt<<1], mx[rt<<1|1]);
}
void update(int rt, int l, int r, int x, int v) {
if(l == r) {
mx[rt] = v;
return ;
}
int mid = (l+r)/2;
if(x <= mid) update(lson, x, v);
else update(rson, x, v);
up(rt);
}
int query(int rt, int l, int r, int L, int R) {
if(L <= l && R >= r)
return mx[rt];
int mid = (l+r)/2;
int ret = 0;
if(L <= mid) ret = max(ret, query(lson, L, R));
if(R >mid) ret = max(ret, query(rson, L, R));
return ret;
}
}st;
int main() {
int n, m, x, y;
char op[2];
while(scanf("%d%d", &n, &m) == 2) {
st.build(1, 1, n);
while(m--) {
scanf("%s%d%d", op, &x, &y);
if(op[0] == 'Q') printf("%d\n", st.query(1, 1, n, x, y));
else st.update(1, 1, n, x, y);
}
}
return 0;
}