【模板】单点更改,单点查询;区间更改,单点查询;区间更改,区间查询(树状数组,线段树)
作者:互联网
文章目录
单点更改,单点查询
例题
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);
}
}
}
区间更改,单点查询
例题
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