1.线段树
#include <bits/stdc++.h>
using namespace std;
int Sum[200001],Add[200001];//Add懒惰标记
int Num[50001]={0,1,2,3,4,5,6};
void create(int l,int r,int rt)
{
if(l==r)
{
Sum[rt]=Num[l];
return ;
}
int mid=(l+r)>>1;
create(l,mid,rt<<1);
create(mid+1,r,rt<<1|1);
Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];
}
void update(int l,int r,int L,int R,int x,int rt)
{
if(L<=l&&R>=r)
{
Sum[rt]+=x*(r-l+1);
Add[rt]+=x;//标记一波
return;
}
int mid=(l+r)>>1;
if(Add[rt])//下推标记更新一波
{
Sum[rt<<1]+=Add[rt]*(mid-l+1);
Sum[rt<<1|1]+=Add[rt]*(r-mid);
Add[rt<<1]+=Add[rt];
Add[rt<<1|1]+=Add[rt];
Add[rt]=0;
}
if(L<=mid)
{
update(l,mid,L,R,x,rt<<1);
}
if(R>mid)
{
update(mid+1,r,L,R,x,rt<<1|1);
}
Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];
}
long long query(int l,int r,int L,int R,int rt)
{
if(L<=l&&R>=r)
{
return Sum[rt];
}
int mid=(l+r)>>1;
if(Add[rt])//下推标记更新一波
{
Sum[rt<<1]+=Add[rt]*(mid-l+1);
Sum[rt<<1|1]+=Add[rt]*(r-mid);
Add[rt<<1]+=Add[rt];
Add[rt<<1|1]+=Add[rt];
Add[rt]=0;
}
long long sum=0;
if(L<=mid)
{
sum+=query(l,mid,L,R,rt<<1);
}
if(R>mid)
{
sum+=query(mid+1,r,L,R,rt<<1|1);
}
return sum;
}
int main()
{
create(1,6,1);
update(1,6,2,5,6,1);
cout << query(1,6,1,3,1) << endl;
cout << query(1,6,1,6,1) << endl;
cout << query(1,6,2,5,1) << endl;
cout << query(1,6,2,2,1) << endl;
cout << query(1,6,1,1,1) << endl;
return 0;
}
线段树更新
处理实际问题的时候还可能涉及到区间信息合并等操作,需要根据实际情况对线段树进行修改
相关例题 HDU1540,HDU3911
2.树状数组
int c[maxn];
int lowbit(int x)
{
return x&(-x);
}
void updata(int x,int y,int n)
{
for(int i=x;i<=n;i+=lowbit(i))
c[i]+=y;
}
int FIND(int x)
{
int ans=0;
for(int i=x;i;i-=lowbit(i))
ans+=c[i];
return ans;
}
3.RMQ
https://blog.csdn.net/qq_41311604/article/details/79900893