线段树+树状数组题目导引
PS:http://www.notonlysuccess.com/index.php/segment-tree-complete/
线段树很好的博客;
HDU:http://acm.hdu.edu.cn/showproblem.php?pid=1754
求区间的最大值:#include <cstdio>
#include<algorithm>
#include<math.h>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 255555;
int sum[maxn<<2];
void PushUP(int rt) {
sum[rt] = max(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(lson);
build(rson);
PushUP(rt);
}
void update(int p,int add,int l,int r,int rt) {
if (l == r) {
sum[rt] = add;
return ;
}
int m = (l + r) >> 1;
if (p <= m) update(p , add , lson);
else update(p , add , rson);
PushUP(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 = max(ret,query(L , R , lson));
if (R > m) ret = max(ret,query(L , R , rson));
return ret;
}
int main() {
int n,m;
while (scanf("%d%d",&n,&m)!=EOF) {
memset(sum,0,sizeof(sum));
build(1 , n , 1);
while (m--) {
char s[2];
int a,b;
scanf("%s%d%d",s,&a,&b);
if (s[0]=='Q') printf("%d\n",query(a,b,1,n,1));
else update(a,b,1,n,1);
}
}
return 0;
}
#include<math.h>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 255555;
int sum[maxn<<2];
void PushUP(int rt) {
sum[rt] = max(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(lson);
build(rson);
PushUP(rt);
}
void update(int p,int add,int l,int r,int rt) {
if (l == r) {
sum[rt] = add;
return ;
}
int m = (l + r) >> 1;
if (p <= m) update(p , add , lson);
else update(p , add , rson);
PushUP(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 = max(ret,query(L , R , lson));
if (R > m) ret = max(ret,query(L , R , rson));
return ret;
}
int main() {
int n,m;
while (scanf("%d%d",&n,&m)!=EOF) {
memset(sum,0,sizeof(sum));
build(1 , n , 1);
while (m--) {
char s[2];
int a,b;
scanf("%s%d%d",s,&a,&b);
if (s[0]=='Q') printf("%d\n",query(a,b,1,n,1));
else update(a,b,1,n,1);
}
}
return 0;
}
HDU 1166;更新点值求区间
修改区间求区间值:
题目:http://acm.fzu.edu.cn/problem.php?pid=2171
模板: http://www.cnblogs.com/forgot93/p/3700449.html
PKU2777:抄HH模板过头了,自己根本没理解深透,然后TLE了好久;
HDU 3308LCIS:
找BUG找了很久,虽然思路不是自己的,怪自己没理解偷模板,然后就输出一些奇怪的东西。。。
小小总结一下:
跟新区间用 LAZY标记法,然后又一个 PUSHDOWN,和PUSHUP操作,
更新点的话就有一个PUSHUP操作就可以了
2:多次询问一个连续区间的某些特征时,一般要把改区间分为左右两区间进行操作。
随性Code