ACM——(线段树)

ACM——(线段树)_第1张图片

1线段树修改(modify)

int s[maxn*4];//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);
}

你可能感兴趣的:(#,线段树)