1线段树修改(modify)
int s[maxn*4];
A(父结点—>子结点)结点值的更新
void modify(int p,int left,int right,int spot,int value)
{
s[p]+=value;
if(left==right)
return ;
int mid=(left+right)/2;
if(spot<=mid)
modify(p*2,left,mid,spot,value);
else
modify(p*2+1,mid+1,right,spot,value);
}
B(子结点—>父结点)结点值得更新
void up(int p)
{
s[p]=s[p*2]+s[p*2+1];
}
void modify(int p,int left,int right,int spot,int value)
{
if(left==right)
{
s[p]+=value;
return ;
}
int mid=(left+right)/2;
if(spot<=mid)
modify(p*2,left,mid,spot,value);
else
modify(p*2+1,mid+1,right,spot,value);
up(p);
}
2线段树查询(query)
int query(int p,int left,int right,int x,int y)
{
if(x<=left&&y>=right)
return s[p];
int mid=(left+right)/2,ans=0;
if(x<=mid)
ans+=query(p*2,left,mid,x,y);
if(y>mid)
ans+=query(p*2+1,mid+1,right,x,y);
return ans;
}
RMQ
const int N=50000+5;
int dp_min[N][100],a[N],n,dp_max[N][100];
void RMQ()
{
for(int i=1;i<=n;i++)
{
dp_min[i][0]=a[i];
dp_max[i][0]=a[i];
}
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
{
dp_min[i][j]=min(dp_min[i][j-1],dp_min[i+(1<<j-1)][j-1]);
dp_max[i][j]=max(dp_max[i][j-1],dp_max[i+(1<<j-1)][j-1]);
}
}
int query(int l,int r)
{
int k=log2(r-l+1);
return max(dp_max[l][k],dp_max[r-(1<<k)+1][k])-min(dp_min[l][k],dp_min[r-(1<<k)+1][k]);
}
一维树状数组
void add(ll p, ll x){
for(int i = p; i <= n; i += i & -i)
sum1[i] += x, sum2[i] += x * p;
}
void range_add(ll l, ll r, ll x){
add(l, x), add(r + 1, -x);
}
ll ask(ll p){
ll res = 0;
for(int i = p; i; i -= i & -i)
res += (p + 1) * sum1[i] - sum2[i];
return res;
}
ll range_ask(ll l, ll r){
return ask(r) - ask(l - 1);
}