线段树题记

hdu-1166 敌兵布阵

  • 简单的单点修改,区间查询
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int Max_n=5e4+10;

int tree[Max_n<<2];

void pushUp(int rt){
	tree[rt]=tree[rt<<1]+tree[rt<<1|1];
}

void build(int l,int r,int rt){
	if(l==r){
		scanf("%d",&tree[rt]);
		return;
	}
	int m=(l+r)>>1;
	build(lson);build(rson);
	pushUp(rt);
}

void update(int k,int value,int l,int r,int rt){ //单点更新 
	if(l==r){
		tree[rt]+=value;
		return;
	} 
	int m=(l+r)>>1;
	if(k<=m)update(k,value,lson);
	else update(k,value,rson);
	pushUp(rt);
} 

int query(int L,int R,int l,int r,int rt){
	if(r<=R&&l>=L)return tree[rt];
	int ans=0;
	int m=(l+r)>>1;
	if(L<=m)ans+=query(L,R,lson);
	if(R>=m+1)ans+=query(L,R,rson);
	return ans; 
}

int main()
{
	int T,n;
	scanf("%d",&T);
	for(int i=1;i<=T;i++){
		printf("Case %d:\n",i);
		scanf("%d",&n); 
		build(1,n,1);
		char s[110];
		int x,y;
		while(~scanf("%s",s)&&s[0]!='E'){
			scanf("%d%d",&x,&y);
			if(s[0]=='A')update(x,y,1,n,1);
			else if(s[0]=='S')update(x,-y,1,n,1);
			else printf("%d\n",query(x,y,1,n,1));
		}
	}
	return 0;
}

poj 2352 Stars

  • 单点修改,区间查询(在每一个点更新之前,进行区间查询)
  • 注意x=0!会死循环
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 
const int Max_n=32100;

int ans[Max_n];
int tree[Max_n<<2];

void pushUp(int rt){
	tree[rt]=tree[rt<<1]+tree[rt<<1|1]; 
}

void update(int k,int value,int l,int r,int rt){
	if(l==r){
		tree[rt]+=value;
		return;
	}
	int m=(l+r)>>1;
	if(k<=m)update(k,value,lson);
	else update(k,value,rson);
	pushUp(rt);
}

int query(int L,int R,int l,int r,int rt){
	if(l>=L&&r<=R)return tree[rt];
	int ans=0;
	int m=(l+r)>>1;
	//cout<<l<<' '<<r<<' '<<rt<<endl;
	if(L<=m)ans+=query(L,R,lson);
	if(R>=m+1)ans+=query(L,R,rson);
	return ans;
}

int main()
{
	int n,x,y;
	scanf("%d",&n);
	memset(ans,0,sizeof(ans));
	memset(tree,0,sizeof(tree));
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);x++;  //避免x=0 
		ans[query(1,x,1,Max_n,1)]++;
		update(x,1,1,Max_n,1);
	}
	for(int i=0;i<n;i++)
		printf("%d\n",ans[i]);
	return 0;
}

poj 3468 A Simple Problem with Integers

  • 区间修改,区间查询(lazy标记)
  • lazy标记思想:更新到某个区间的时候,先给这个区间打上lazy标记,不去更新子区间。当下一次更新子区间的时候再把该区间的lazy标记更新到子区间。从而避免浪费更新那些不必要的结点的时间。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std; 
typedef long long ll;
const int Max_n=1e5+10;

int s[Max_n];
ll sum[Max_n<<2];
int lazy[Max_n<<2];

void pushUp(int rt){
	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

void pushDown(int rt,int len){
	if(lazy[rt]){
		lazy[rt<<1]+=lazy[rt];
		lazy[rt<<1|1]+=lazy[rt];
		sum[rt<<1]+=(len-(len>>1))*lazy[rt];
		sum[rt<<1|1]+=(len>>1)*lazy[rt];
		lazy[rt]=0;
	}
}

void build(int l,int r,int rt){
	lazy[rt]=0;
	if(l==r){
		sum[rt]=s[l];
		return;
	}
	int m=(l+r)>>1;
	build(lson);build(rson);
	pushUp(rt);
}

void update(int L,int R,int c,int l,int r,int rt){
	if(l>=L&&r<=R){
		lazy[rt]+=c;
		sum[rt]+=(ll)c*(r-l+1);
		return;
	}
	int m=(l+r)>>1;
	pushDown(rt,r-l+1);
	if(L<=m)update(L,R,c,lson);
	if(R>=m+1)update(L,R,c,rson);
	pushUp(rt);
}

ll query(int L,int R,int l,int r,int rt){
	if(l>=L&&r<=R)return sum[rt];
	pushDown(rt,r-l+1);
	int m=(l+r)>>1;
	ll ans=0;
	if(L<=m)ans+=query(L,R,lson);
	if(R>=m+1)ans+=query(L,R,rson);
	return ans;
}

int main()
{
	int n,t;
	scanf("%d%d",&n,&t);
	for(int i=1;i<=n;i++)scanf("%d",&s[i]);
	build(1,n,1);
	char ch;
	int x,y,z;
	while(t--){
		cout<<t<<'&'<<endl;
		scanf("%c",&ch);
		if(ch=='Q'){
			scanf("%d%d",&x,&y);
			printf("%lld\n",query(x,y,1,n,1));
		} 
		else {
			scanf("%d%d%d",&x,&y,&z);
			update(x,y,z,1,n,1);
		}
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值