0
点赞
收藏
分享

微信扫一扫

线段树学习及练习

搬砖的小木匠 2022-03-11 阅读 81

线段树学习博客:线段树 从入门到进阶(超清晰,简单易懂)

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;
}

举报

相关推荐

0 条评论