线段树模板


注意了,线段树的空间是4倍,MAXN*4

无lasy标记 hdu1754

#include<iostream>
#include<string>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define MAXN 200005
int n,m,a[MAXN];
struct node {
	int l,r,maxn;//最大值,最小值,还是sum,根据题目来 
} tree[MAXN*4+5];
void build(int id,int l,int r) { //id是节点编号,l,r是当前节点所包含的区间范围
	tree[id].l=l;
	tree[id].r=r; //建立第id个节点,它管理区间为l-r
	if(l==r) { //如果是叶子节点,直接输入数据并返回
		scanf("%d",&tree[id].maxn);
		return;
	} else { //如果不是叶子节点
		int mid=(l+r)>>1; //mid为它区间中点
		build(id<<1,l,mid);//当mid小于等于左边区间建左子树
		build(id<<1|1,mid+1,r);//建右子树
		tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn);//更新区间最大值
	}
}
void update(int id,int pos,int val) { //id是节点编号,pos是要更新的点
	if(tree[id].l==tree[id].r) { //找到要更新的点,赋值并返回
		tree[id].maxn=val;
		return;
	} else {
		int mid=(tree[id].l+tree[id].r)>>1;//mid为节点区间中点
		if(pos<=mid) update(id<<1,pos,val);//点的位置在当前节点管理区间左半部分,
		else update(id<<1|1,pos,val); //点的位置在当前节点管理区间右半部分,
		tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn);
	}
}
int query(int id,int l,int r) { //id是节点编号,l,r是要查询区间
	if(tree[id].l==l&&tree[id].r==r) { //找到区间
		return tree[id].maxn;
	} else {
		int mid=(tree[id].l+tree[id].r)>>1; //mid是当前节点管理区间的中点
		if(r<=mid) return query(id<<1,l,r); //要查询区间完全在左子树上
		else if(l>mid) return query(id<<1|1,l,r);//要查询区间完全在右子树上
		else return max(query(id<<1,l,mid),query(id<<1|1,mid+1,r)); //要查询区间分为两部分,取其中最大的一个
	}
}
int main() {
	while(cin>>n>>m) {
		build(1,1,n);
		while(m--) {
			char ch;
			cin>>ch;
			int l,r;
			cin>>l>>r;
			if(ch=='Q') {
				cout<<query(1,l,r)<<endl;
			} else {
				update(1,l,r);
			}
		}
	}
	return 0;
}

lazy标记 poj3468

#include <iostream>
#include <stdio.h>
using namespace std;
//区间更新+lasy
#define MAXN 100005
struct node {
	int l,r;
	long long lazy;
	long long sum;
} tree[MAXN*4+5];
int a[MAXN+5];
void pushdown(int id) {
	if(tree[id].lazy!=0) {
		tree[id*2].lazy+=tree[id].lazy;
		tree[id*2+1].lazy+=tree[id].lazy;
		tree[id*2].sum+=(tree[id].lazy*(tree[id*2].r-tree[id*2].l+1));
		tree[id*2+1].sum+=(tree[id].lazy*(tree[id*2+1].r-tree[id*2+1].l+1));
		tree[id].lazy=0;
	}
}
void build (int left,int right,int id) {
	tree[id].l=left;
	tree[id].r=right;
	tree[id].lazy=0;
	int mid=(left+right)/2;
	if(tree[id].l==tree[id].r) {
		tree[id].sum=a[tree[id].l];
		return ;
	} else {
		build(left,mid,id*2);
		build(mid+1,right,id*2+1);
	}
	tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
}
void add(int left,int right,int val,int id) {
	int mid=(tree[id].l+tree[id].r)/2;
	if(left<=tree[id].l&&tree[id].r<=right) {
		tree[id].lazy+=val;
		tree[id].sum+=(val*(tree[id].r-tree[id].l+1));
		return ;
	}
	pushdown(id);//lazy下放 
	if(right<=mid) {
		add(left,right,val,id*2);
	} else if(left>=mid+1) {
		add(left,right,val,id*2+1);
	} else {
		add(left,mid,val,id*2);
		add(mid+1,right,val,id*2+1);
	}
	tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;//子树值变了,根结点也要改变,相当于pushup 
}
long long inquiry(int left,int right,int id) {
	int mid=(tree[id].l+tree[id].r)/2;
	if(left<=tree[id].l&&tree[id].r<=right) {
		return tree[id].sum;
	}
	pushdown(id);
	long long ans=0;
	if(right<=mid) {
		ans+=inquiry(left,right,id*2);
	} else if(left>=mid+1) {
		ans+=inquiry(left,right,id*2+1);
	} else {
		ans+=inquiry(left,mid,id*2);
		ans+=inquiry(mid+1,right,id*2+1);
	}
	return ans;
}
int main () {
	int n,m;
	cin>>n>>m;
	for (int i=1; i<=n; i++) {
		cin>>a[i];
	}
	build(1,n,1);
	while (m--) {
		char ch;
		cin>>ch;
		if(ch=='Q') {
			int x,y;
			cin>>x>>y;
			long long ans=inquiry(x,y,1);
			cout<<ans<<endl;
		} else if(ch=='C') {
			int x,y,val;
			cin>>x>>y>>val;
			add(x,y,val,1);
		}
	}
}

放一个别人代码,对应着看不同点hdu4027

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=100005;
long long a[maxn];
long long sum[maxn*4];
int t,x,y;
void Build(int o,int l,int r) {
	if(l==r) {
		sum[o]=a[l];
		return ;
	}
	int mid=l+r>>1;
	Build(o<<1,l,mid);
	Build(o<<1|1,mid+1,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
void Update(int o,int l,int r) {
	if(x<=l&&r<=y&&r-l+1==sum[o]) {
		return ;
	}
	if(l==r) {
		sum[o]=sqrt(sum[o]);
		return ;
	}
	int mid=l+r>>1;
	if(x<=mid) {
		Update(o<<1,l,mid);
	}
	if(y>mid) {
		Update(o<<1|1,mid+1,r);
	}
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
long long Query(int o,int l,int r) {
	long long ans=0;
	if(x<=l&&r<=y) {
		return sum[o];
	}
	int mid=l+r>>1;
	if(x<=mid) {
		ans+=Query(o<<1,l,mid);
	}
	if(y>mid) {
		ans+=Query(o<<1|1,mid+1,r);
	}
	return ans;
}
int main() {
	int n;
	int cnt=0;
	while(~scanf("%d",&n)) {
		for(int i=1; i<=n; i++) {
			scanf("%lld",&a[i]);
		}
		Build(1,1,n);
		int m;
		printf("Case #%d:\n",++cnt);
		scanf("%d",&m);
		while(m--) {
			scanf("%d%d%d",&t,&x,&y);
			if(y<x) swap(x,y);
			if(t==0) {
				Update(1,1,n);
			} else {
				printf("%lld\n",Query(1,1,n));
			}
		}
		printf("\n");
	}
}
posted @ 2021-07-30 10:41  cheems~  阅读(26)  评论(0编辑  收藏  举报