题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
线段树
此题空间极小,注意爆空间
如果开数组,延迟标记就算了= =,左右下标也算了,直接递归带参数跑= =
贴代码
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=200005;
int tree[maxn*20];//addflag[maxn*20];
int a[maxn];
int max(int x,int y){
return x>y?x:y;
}
void build(int root,int L,int R){
// addflag[root]=0;
if (L==R)tree[root]=a[L];
else{
int mid=(L+R)/2;
build(root*2,L,mid);
build(root*2+1,mid+1,R);
tree[root]=max(tree[root*2],tree[root*2+1]);
}
}
/*void pushdown(int root){
if (addflag[root]!=0){
addflag[root*2]+=addflag[root];
addflag[root*2+1]+=addflag[root];
tree[root*2]+=addflag[root];
tree[root*2+1]+=addflag[root];
addflag[root]=0;
}
}*/
int query(int root,int l,int r,int L,int R){
if ((r<L)||(R<l))return -1;
if ((L>=l)&&(R<=r))return tree[root];
// pushdown(root);
int mid=(L+R)>>1;
return max(query(root*2,l,r,L,mid),query(root*2+1,l,r,mid+1,R));
}
void add(int root,int l,int r,int L,int R,int delta){
if ((r<L)||(R<l))return;
if ((L>=l)&&(R<=r)){
// addflag[root]+=delta;
tree[root]+=delta;
return;
}
// pushdown(root);
int mid=(L+R)>>1;
add(root*2,l,r,L,mid,delta);
add(root*2+1,l,r,mid+1,R,delta);
tree[root]=max(tree[root*2],tree[root*2+1]);
}
int main(){
// freopen("1754.in","r",stdin);
// freopen("1754.out","w",stdout);
int n,m;
while(scanf("%d%d\n",&n,&m)!=EOF){
memset(tree,0,sizeof(tree));
// memset(addflag,0,sizeof(addflag));
for (int i=1;i<=n;i++)scanf("%d",&a[i]);
scanf("\n");
build(1,1,n);
for (int i=1;i<=m;i++){
int x,y;
char ch;
scanf("%c",&ch);
scanf("%d%d\n",&x,&y);
if (ch=='U'){
int z=query(1,x,x,1,n);
add(1,x,x,1,n,y-z);
}else if (ch=='Q')printf("%d\n",query(1,x,y,1,n));
}
}
return 0;
}
【写的有漏洞的,欢迎路过大神吐槽】
2017/07/11 19:35:37
Ending.