ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【模板】单点更改,单点查询;区间更改,单点查询;区间更改,区间查询(树状数组,线段树)

2021-05-03 12:01:14  阅读:195  来源: 互联网

标签:rt 单点 val sread 更改 int segtree al 查询


文章目录

单点更改,单点查询

例题

Luogu:P3374

Code

树状数组

//树状数组
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define rg register
using namespace std;
typedef long long ll;
inline int sread()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
	return f*x; 
}
const int maxn=5e5+10;
int a[maxn],ops,x,y,k,n,m,ans,c[maxn];
int lowbit(int x)
{
	return x&(-x);
}
void update(int x,int val)
{
	for(rg int i=x;i<=n;i+=lowbit(i)) c[i]+=val;
}
int getsum(int x)
{
	int sum=0;
	for(rg int i=x;i;i-=lowbit(i)) sum+=c[i];
	return sum;
}
int main()
{
	n=sread();	m=sread();
	for(rg int i=1;i<=n;++i)
	{
		a[i]=sread();
		update(i,a[i]);	
	}
	for(rg int i=1;i<=m;++i)
	{
		ops=sread();
		if(ops==1) 
		{
			x=sread();	k=sread();
			update(x,k);
		}
		else if(ops==2)
		{
			x=sread();	y=sread();
			ans=getsum(y)-getsum(x-1);
			printf("%d\n",ans);
		}
	} 
	return 0;
}

线段树

//线段树
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define rg register
using namespace std;
inline int sread()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
	return f*x;
}
const int maxn=500050;
struct segtreenode{
	int val;
}segtree[4*maxn];
int n,m,q,w,x,ans;
int a[maxn+10];

void make_tree(int rt,int al,int ar)
{
	if(al==ar)
	{
		segtree[rt].val=a[al]; return;
	}
	int mid=(al+ar)/2;
	make_tree(rt*2,al,mid);
	make_tree(rt*2+1,mid+1,ar);
	segtree[rt].val=segtree[rt*2].val+segtree[rt*2+1].val;
}
void szupdate(int rt,int al,int ar,int x,int val)
{
	if(al==ar)
	{
		if(al==x)	segtree[rt].val+=val;
		return; 
	}
	int mid=(al+ar)/2;
	if(x<=mid) szupdate(rt*2,al,mid,x,val);
	else szupdate(rt*2+1,mid+1,ar,x,val); 
	segtree[rt].val=segtree[rt*2].val+segtree[rt*2+1].val;
}
int szquery(int rt,int al,int ar,int ql,int qr)
{
	if(al>qr||ar<ql) return 0;
	if(ql<=al&&qr>=ar) return segtree[rt].val;
	int mid=(al+ar)/2;
	return (szquery(rt*2,al,mid,ql,qr)+szquery(rt*2+1,mid+1,ar,ql,qr));
}
int main()
{
	n=sread(); m=sread();
	for(rg int i=1;i<=n;++i)
		a[i]=sread();
	make_tree(1,1,n);
	for(rg int i=1;i<=m;++i)
	{
		q=sread(); x=sread(); w=sread();
		if(q==1) szupdate(1,1,n,x,w);	
		if(q==2)
		{
			ans=szquery(1,1,n,x,w);
			printf("%d\n",ans);
		}
	}
}

区间更改,单点查询

例题

Luogu:P3368

Code

树状数组

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define rg register
using namespace std;
typedef long long ll;
inline int sread()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
	return f*x; 
}
const int maxn=5e5+10;
int a[maxn],ops,x,y,k,n,m,ans,c[maxn];
int lowbit(int x)
{
	return x&(-x);
}
void update(int x,int val)
{
	for(rg int i=x;i<=n;i+=lowbit(i)) c[i]+=val;
}
int getsum(int x)
{
	int sum=0;
	for(rg int i=x;i;i-=lowbit(i)) sum+=c[i];
	return sum;
}
int main()
{
	n=sread();	m=sread();
	for(rg int i=1;i<=n;++i)
	{
		a[i]=sread();
	}
	for(rg int i=1;i<=m;++i)
	{
		ops=sread();
		if(ops==1) 
		{
			x=sread();	y=sread();	k=sread();
			update(x,k); update(y+1,(-1)*k);
		}
		else if(ops==2)
		{
			x=sread();
			ans=a[x]+getsum(x);
			printf("%d\n",ans);
		}
	} 
	return 0;
}

线段树

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define rg register
#define ll long long 
using namespace std;
inline int sread()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
	return f*x; 
}
const int maxn=500050;
const int INF=0x7fffffff;
struct node{
	int val;int lazytag;
}segtree[4*maxn];
int a[maxn+10];
int minn(int a,int b)
{
	return a<b?a:b;
}

void make_tree(int rt,int al,int ar)
{
	segtree[rt].lazytag=0;
	if(al==ar)
	{
		segtree[rt].val=a[al]; return;
	}
	int mid=(al+ar)>>1;
	make_tree(2*rt,al,mid);
	make_tree(2*rt+1,mid+1,ar);
	segtree[rt].val=minn(segtree[2*rt].val,segtree[2*rt+1].val);
}

void pushdown(int rt,int al,int ar)
{
	if(al!=ar&&segtree[rt].lazytag!=0)
	{
		segtree[2*rt].val+=segtree[rt].lazytag;
		segtree[2*rt].lazytag+=segtree[rt].lazytag;
		segtree[2*rt+1].val+=segtree[rt].lazytag;
		segtree[2*rt+1].lazytag+=segtree[rt].lazytag;
		segtree[rt].lazytag=0;
	}
}

int szquery(int rt,int al,int ar,int ql,int qr)//a:被查询 q:查询 
{
	if(ql>ar||qr<al) return INF;
	if(al>=ql&&ar<=qr)
	{
		return segtree[rt].val;
	}
	pushdown(rt,al,ar);
	int mid=(al+ar)>>1;
	return minn(szquery(2*rt,al,mid,ql,qr),szquery(2*rt+1,mid+1,ar,ql,qr));
}

void szupdate(int rt,int al,int ar,int ql,int qr,int val)
{
	if(al>qr||ar<ql) return;
	if(ql<=al&&ar<=qr)
	{
		segtree[rt].val+=val;
		segtree[rt].lazytag+=val;
		return;
	}
	pushdown(rt,al,ar);
	int mid=(al+ar)>>1;
	szupdate(2*rt,al,mid,ql,qr,val);
	szupdate(2*rt+1,mid+1,ar,ql,qr,val);
	segtree[rt].val=minn(segtree[2*rt].val,segtree[2*rt+1].val);
}

int n,m;
int x,y,k,p;
int main()
{
	n=sread();m=sread();
	for(rg int i=1;i<=n;++i)
		a[i]=sread();
	make_tree(1,1,n);
	for(rg int i=1;i<=m;++i)
	{
		p=sread();
		if(p==2)
		{
			x=sread();
			printf("%d\n",szquery(1,1,n,x,x));
		}
		if(p==1)
		{
			x=sread();y=sread();k=sread();
			szupdate(1,1,n,x,y,k);
		}
	}
	return 0;
}

区间更改,区间查询

例题

标签:rt,单点,val,sread,更改,int,segtree,al,查询
来源: https://blog.csdn.net/m0_54182833/article/details/116375608

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有