线段树学习博客:线段树 从入门到进阶(超清晰,简单易懂)
1 . P3374 【模板】树状数组 1 (单点修改,区间查询)
#include <bits/stdc++.h>
using namespace std;
const int MAX=500010;
int a[MAX];
int res=0;
struct node
{
int l,r;
int num;
}t[MAX*4];
void build(int i,int l,int r)
{
t[i].l=l;
t[i].r=r;
t[i].num=0;
if(l==r)
{
t[i].num=a[l];
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
t[i].num=t[i*2].num+t[i*2+1].num;
}
//区间修改
void add(int i,int l,int r ,int k)
{
if(t[i].l>=l && t[i].r<=r)
{
t[i].num+=k;
return ;
}
int mid=(t[i].l+t[i].r)>>1;
if(l<=mid)
add(i*2,l,r,k);
if(r>mid)
add(i*2+1,l,r,k);
}
//单点查询
void ffind(int i,int x)
{
res+=t[i].num;
if(t[i].l==t[i].r)
return;
int mid=(t[i].l+t[i].r)>>1;
if(x<=mid)
ffind(i*2,x);
else
ffind(i*2+1,x);
}
//单点修改
void add1(int i,int d,int k)
{
if(t[i].l==t[i].r)
{
t[i].num+=k;
return ;
}
if(d<=t[i*2].r)
{
add1(i*2,d,k);
}
else
{
add1(i*2+1,d,k);
}
t[i].num=t[i*2].num+t[i*2+1].num;
return ;
}
//区间查询
int ffind1(int i,int l,int r)
{
if(t[i].l>=l && t[i].r<=r)
{
return t[i].num;
}
if(t[i].l>r ||t[i].r<l)
return 0;
int s=0;
if(t[i*2].r>=l)
s+=ffind1(i*2,l,r);
if (t[i*2+1].l<=r)
s+=ffind1(i*2+1,l,r);
return s;
}
int main()
{
std::ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
int id,x,y,k;
while(m--)
{
cin>>id;
if(id==1)
{
cin>>x>>k;
add1(1,x,k);
}
else if(id==2)
{
cin>>x>>y;
res=ffind1(1,x,y);
cout<<res<<endl;
}
}
return 0;
}
2 . P3368 【模板】树状数组 2 (区间修改,单点查询)
#include <bits/stdc++.h>
using namespace std;
const int MAX=500010;
int a[MAX];
int res=0;
struct node
{
int l,r;
int num;
}t[MAX*4];
void build(int i,int l,int r)
{
t[i].l=l;
t[i].r=r;
t[i].num=0;
if(l==r)
{
t[i].num=a[l];
return ;
}
int mid=(l+r)>>1;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
//t[i].num=t[i*2].num+t[i*2+1].num;
}
//区间修改
void add(int i,int l,int r ,int k)
{
if(t[i].l>=l && t[i].r<=r)
{
t[i].num+=k;
return ;
}
int mid=(t[i].l+t[i].r)>>1;
if(l<=mid)
add(i*2,l,r,k);
if(r>mid)
add(i*2+1,l,r,k);
}
//单点查询
void ffind(int i,int x)
{
res+=t[i].num;
if(t[i].l==t[i].r)
return;
int mid=(t[i].l+t[i].r)>>1;
if(x<=mid)
ffind(i*2,x);
else
ffind(i*2+1,x);
}
int main()
{
std::ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
while(m--)
{
int id,x,y,k;
cin>>id;
if(id==1)
{
cin>>x>>y>>k;
add(1,x,y,k);
}
else if(id==2)
{
cin>>x;
res=0;
ffind(1,x);
cout<<res<<endl;
}
}
return 0;
}