其他分享
首页 > 其他分享> > 【模板】单点更改,单点查询;区间更改,单点查询;区间更改,区间查询(树状数组,线段树)

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

作者:互联网

文章目录

单点更改,单点查询

例题

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