Line Segment Tree + Tree Array

Keywords: PHP

Tree Array Topic Set:

AHDU1556
BPOJ2155
CPOJ2299
DPOJ3067
EPOJ2352
FPOJ2481
GPOJ3321
HPOJ1990

 

 

The array must start from 1, because the root node starts from 1.

 

 

P3368 [Template] Tree Array 2

Portal: https://www.luogu.org/problemnew/solution/P3368

The ti tle is called Tree Array, so of course it's written in the direction of Tree Array, but after I use simple operation, let's go.

After reading the blog of Big Man, I learned that the difference of tree array can be used together.

(https://blog.csdn.net/qq_41292370/article/details/82708214)

Optimizing the Time Complexity of Interval Modification Operations by Using the Properties of Differences

Optimizing the Time Complexity of Query Operations by Using the Properties of Tree Arrays

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<string>
#include<cmath>
#include<sstream>
using namespace std;
typedef long long ll;
const double pi=acos(-1.0);
const int eps=1e-10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
const int maxn=500005;
class TA
{
    private:
        int e[maxn];
        int len;
        int lowbit(int k)
        {
            return k & (-k);
        }
    public:
        void add(int x,int v)                                                    //Interval updating
        {
            while(x <= len)
            {
                e[x] += v;
                x += lowbit(x);
            }
        }
        void init(int* getin,int _len)                                            //Initialization
        {
            len = _len;
            for(int i = 1;i <= len;i ++)
            {
                add(i,*(getin + i - 1));
             }
        }
        ll getsum(int x)                                                        //inquiry
        {
            ll sum = 0;
            while(x > 0)
            {
                sum += e[x];
                x -= lowbit(x);
            }
            return sum;
        }

};

TA ta;
int a[maxn],n,t,m,b[maxn];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d",&a[i]);
    }
    b[1] = a[1];
    for(int i = 2;i <= n;i++)
    {
        b[i] = a[i] - a[i - 1];
    }
    ta.init(b + 1,n);
    while(m--)
    {
        int idenx,x,y,k;
        scanf("%d",&idenx);
        if(idenx == 1)
        {
            scanf("%d%d%d",&x,&y,&k);
            ta.add(x,k);
            ta.add(y + 1,-k);
        }
        else
        {
            scanf("%d",&x);
            printf("%lld\n",ta.getsum(x));
        }
    }
    return 0;
}

There is also a line segment tree method.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<string>
#include<cmath>
#include<sstream>
using namespace std;
typedef long long ll;
const double pi=acos(-1.0);
const int eps=1e-10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
const int maxn=500005;
int a[maxn];
int ts[maxn << 2],tl[maxn << 2];


void build(int p,int l,int r)
{
    tl[p] = 0;
    if(l == r)
    {
        ts[p] = a[l];
        return;
    }
    int mid = (l + r) / 2;
    build(p * 2,l,mid);
    build(p * 2 + 1,mid + 1,r);
    ts[p] = ts[p * 2] + ts[p * 2 + 1];
    return;
}

void pushdown(int p,int l,int r)
{
    int mid = (l + r) / 2;

    ts[p *2] += tl[p] * (mid - l + 1);
    ts[p * 2 + 1] += tl[p] * (r - mid); 
    tl[p * 2] += tl[p];
    tl[p * 2 + 1] += tl[p];
    tl[p] = 0;
    return;
}

void updata(int p,int l,int r,int x,int y,ll k)
{
    if(l > y || r < x)return;
    if( x <= l && y >= r)
    {
        ts[p] += k * (l - r + 1);
        tl[p] += k;
        return;
    }
    pushdown(p,l,r);
    int mid = (l + r) / 2;
    updata(2 * p, l,mid,x,y,k);
    updata(2 * p + 1,mid + 1,r,x,y,k);
    ts[p] = (ts[p * 2] + ts[p * 2 + 1]);
    return;
}

//error 
ll query(int p,int l,int r,int x,int y) 
{
    if(x > r || y < l)return 0;
    if(x <= l && y >= r)return ts[p];
    pushdown(p,l,r);
    int mid = (l + r) / 2;
    return (query(2 * p,l,mid,x,y)+query(2 * p + 1,mid + 1,r,x,y));
}

int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d",&a[i]);
    }
    build(1,1,n);
    while(m--)
    {
        int index,x,y;
        ll k;
        scanf("%d",&index);
        if(index == 1)
        {
            scanf("%d%d%lld",&x,&y,&k);
            updata(1,1,n,x,y,k);
        }
        else
        {
            scanf("%d",&x);
            printf("%lld\n",query(1,1,n,x,x));

        }

    }
    return 0;
}

Hee hee

Posted by kanika on Wed, 31 Jul 2019 03:48:00 -0700