1. 线段树

题目:第一行输入数字n,第二行输入n个数字。第三行输入数字m,接下来输入m组数据(操作符p,数字x,数字y)。

其中p=1代表在x位置处+y,p=2对区间(x,y)求和并输出。

样例:

输入

6
4 5 6 2 1 3
4
1 3 5
2 1 4
1 1 9
2 2 6

输出

22

22

#include<cstdio>
#include<iostream>
using namespace std;
int n,m,p,x,y,ans;//n->数据个数 ,m->修改+查询次数 ,p->操作类型,x,y->操作数,ans->求值 
struct node
{
    int l,r,w;//左右边界,权值 
}tree[400001];
inline void build(int l,int r,int k)//内联函数,左边界=l,右边界=r,当前节点数=k,根节点序号为1
{   

    tree[k].l=l;tree[k].r=r;//1,1,6 ||2,1,3 ||4,1,2|| 8,1,1||9,2,2||5,3,3||3,4,6||6,4,5||12,4,4||13,5,5||7,6,6(k,l,r)
    if(l==r) //l=r=1||l=r=2 ||l=r=3||l=r=4||l=r=5||l=r=6
    {
        scanf("%d",&tree[k].w);//输入值tree[8].w=4 ||输入值 tree[9].w=5||输入值tree[5].w=6 ||tree[12].w=2||tree[13].w=1||tree[7].w=3
        return ;
    }
    int m=(l+r)/2;//m为中点
    //cout<<"建树过程"<< l<<m<<2*k<<endl;
    
    build(l,m,k*2);//建树(1,3,2) ||建树(1,2,4) ||建树(1,1,8) (此时 l=1,r=2,m=1) ||建树(4,5,6)||建树(4,4,12) 
    //cout<<"建树过程"<< m+1<<r<<2*k+1<<endl;
    build(m+1,r,k*2+1);//树(1,1,8)已经建成返回,开始建树 (2,2,9) ||  建树(3,3,5)||建树(4,6,3) ||建树(5,5,13)||建树(6,6,7) 
    tree[k].w=tree[k*2].w+tree[k*2+1].w;//tree[4].w= 4+5=9||tree[2].w=9+6=15||tree[6].w=2+1=3||tree[3].w=3+3=6||tree[1].w=15+6=21
}
inline void add(int k)//k=1,(x=3,y=5)
{
    if(tree[k].l==tree[k].r)//找到该位置 
    {
        tree[k].w+=y;
        return;
    }
    int m=(tree[k].l+tree[k].r)/2;
    if(x<=m) add(k*2);//x在左树    else add(k*2+1);
    tree[k].w=tree[k*2].w+tree[k*2+1].w; 
}
inline void sum(int k)
{   if(tree[k].l>=x&&tree[k].r<=y) 
    {
        ans+=tree[k].w;
        return;
    }
    int m=(tree[k].l+tree[k].r)/2;
    if(x<=m) sum(k*2);
    if(y>m) sum(k*2+1);
}
int main()
{
    scanf("%d",&n);//输入n个数 
    build(1,n,1);// 建立线段树 
    scanf("%d",&m);//输入操作次数 
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&p,&x,&y);
        ans=0;
        if(p==1) add(1);
        else 
        {
            sum(1);
            printf("%d\n",ans);
        }
    }
}

ps:线段树结构的三个元素为左右边界和权值,真正的数据存储在结点(即左右边界相等的地方),(本题中)其他结点权值存储的是左右孩子的和。从1开始进行双递归建树

l==r时为输入结点也是递归出口。查询和操作时也是从1开始条件递归操作,注意找到递归出口。

 

猜你喜欢

转载自www.cnblogs.com/apo2019/p/10737585.html