这两道题,都是裸的线段树,并且线段树维护的都是区间和。放在一起整理一下,毕竟之前只是按照板子敲过。

HDU 1166----单点修改,区间查询

(小声哔哔:用区间来代替单点,一样能A的。毕竟原理都一样。在Add()函数和update( )函数那里,就是if-else的区别?)

线段树模板整理 HDU1166 POJ3468


//ac 单点修改 
//HDU 1166 second
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<set>
#include<queue>
#include<stack> 
using namespace std;
const int maxn=50005;
int num[maxn];
int tree[maxn<<2];

void pushup(int root)
{
	tree[root]=tree[2*root]+tree[2*root+1];
}
void build(int root,int left,int right)
{
	if(left==right)
	{
		tree[root]=num[left];
		return ;
	 } 
	
	int mid=(left+right)/2;
	build(root*2,left,mid);
	build(root*2+1,mid+1,right);
	pushup(root);
}

int Add(int root,int left,int right,int index,int addvalue)
{
	if(left==right)
	{
		tree[root]+=addvalue;
		return 0;
		
	}
	int mid=(left+right)/2;
	if(index<=mid)
		Add(root*2,left,mid,index,addvalue);
	else
		Add(root*2+1,mid+1,right,index,addvalue);
	pushup(root);
	
 } 

int Query(int qleft,int qright,int cleft,int cright,int root)
{
	if(qleft<=cleft && qright>=cright)
	{
		return tree[root];
	}
	
	int mid=(cleft+cright)/2;
	int ans=0;
	if(qleft<=mid)
		ans+=Query(qleft,qright,cleft,mid,root*2);
	if(qright>mid)
		ans+=Query(qleft,qright,mid+1,cright,root*2+1);
	return ans;
}

int main()
{
	int t;
	scanf("%d",&t);
	int tcase=0;
	while(t--)
	{
		printf("Case %d:\n",++tcase);
		
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%d",&num[i]);
		
		build(1,1,n);
		
		string s;
		int i,j;
		while(cin>>s)
		{
			if(s[0]=='E')
				break;
			if(s[0]=='A')
			{
				scanf("%d%d",&i,&j);
				int index=i;
				int addvalue=j;
				Add(1,1,n,index,addvalue);
			}
			else if(s[0]=='S')
			{
				scanf("%d%d",&i,&j);
				int index=i;
				int addvalue=0-j;
				Add(1,1,n,index,addvalue);				
			}
			else if(s[0]=='Q')
			{
				scanf("%d%d",&i,&j);
				int qleft=i;
				int qright=j;
				int res=Query(qleft,qright,1,n,1);
				printf("%d\n",res);
			}
		}
	}
 } 

 

POJ 3468----区间查询,修改

线段树模板整理 HDU1166 POJ3468



//POJ 3468 second
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<set>
#include<queue>
#include<stack> 
using namespace std;
#define ll long long
const int maxn=1e5+5;
int num[maxn];
ll tree[maxn<<2];
ll mark[maxn<<2];

void pushup(int root)
{
	tree[root]=tree[2*root]+tree[2*root+1];
}
void pushdown(int root,int ln,int rn)
{
	if(mark[root])
	{
		tree[2*root]+=(ll)mark[root]*ln;
		tree[2*root+1]+=(ll)mark[root]*rn;
		mark[2*root]+=(ll)mark[root];
		mark[2*root+1]+=(ll)mark[root];
		
		mark[root]=0;
	}
	return;
}

void build(int root,int left,int right)
{
	mark[root]=0;
	if(left==right)
	{
		tree[root]=num[left];
		return;
	}
	int mid=(left+right)/2;
	build(2*root,left,mid);
	build(2*root+1,mid+1,right);
	pushup(root);
	return;
}

ll Query(int qleft,int qright,int left,int right,int root)
{
	if(left>=qleft && right<=qright)//当前区间[left,right] 在查询的区间之内。 
		return tree[root];
	if(right<qleft || left>qright)//没有交集 
		return 0;
		
	int mid=(left+right)/2;
	
	pushdown(root,mid-left+1,right-mid);
	
	ll ans=0;
	if(mid>=qleft)//当前区间中点>区间左端点 
		ans+=Query(qleft,qright,left,mid,2*root);
	if(mid<qright)
		ans+=Query(qleft,qright,mid+1,right,2*root+1);
	return ans;
}

void update(int uleft,int uright,int left,int right,int add,int root)
{
	if(right<uleft || left>uright)
		return;
	if(left>=uleft && right<=uright)
	{
		tree[root]+=(right-left+1)*add;
		mark[root]+=add;
		return ;
	}
	int mid=(left+right)/2;
	pushdown(root,mid-left+1,right-mid);
	if(uleft<=mid)
		update(uleft,uright,left,mid,add,2*root);
	if(uright>mid)
		update(uleft,uright,mid+1,right,add,2*root+1);
		
	pushup(root);//区间更新之后的操作 ,易漏! 
	return ;
}


int main()
{
	int n,q;
	
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)
		scanf("%d",&num[i]);
		
	build(1,1,n);
	


	while(q--)
	{
			char s[2];
			scanf("%s",s);
			if(s[0]=='Q')
			{
				int qright;
				int qleft;
				scanf("%d%d",&qleft,&qright);
				ll res=Query(qleft,qright,1,n,1);
				printf("%lld\n",res);
			}
			else if(s[0]=='C')
			{
				int uleft,uright;
				int addmark;
				scanf("%d%d%d",&uleft,&uright,&addmark);
				update(uleft,uright,1,n,addmark,1);
			}
		
		
	}
 }  

相关文章:

  • 2021-07-18
  • 2022-12-23
  • 2021-08-24
  • 2021-09-05
  • 2022-01-06
  • 2022-12-23
  • 2021-10-01
  • 2021-12-22
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-13
  • 2021-06-03
  • 2022-01-02
  • 2021-09-30
相关资源
相似解决方案