码迷,mamicode.com
首页 > 其他好文 > 详细

线段树(On2)

时间:2019-05-16 20:23:20      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:typedef   sea   c++   turn   arch   +=   end   节点   for   

#include<bits/stdc++.h>
using namespace std;
typedef struct{
    int l,r,w;
}Node;
Node nodes[1000000]={0,0,0};
int x,y,ans,mod,single;
void build(int l,int r,int n)
{//建树
    nodes[n].l=l;nodes[n].r=r;
    if(nodes[n].l==nodes[n].r)
    {
        scanf("%d",&nodes[n].w);
        return;
    }
    build(l,(l+r)/2,n*2);
    build((l+r)/2+1,r,n*2+1);
    nodes[n].w=nodes[n*2+1].w+nodes[n*2].w;
}
void singleSearch(int k)
{//单点查询
    if(nodes[k].l==nodes[k].r)
    {
        printf("%d",nodes[k].w);
        return;
    }
    int mid=(nodes[k].l+nodes[k].r)/2;
    if(single<=mid)singleSearch(k*2);
    else singleSearch(k*2+1);
}
void singleChange(int k)
{//单点修改
    if(nodes[k].l==nodes[k].r)
    {
        nodes[k].w+=mod;
        return;
    }
    int mid=(nodes[k].l+nodes[k].r)/2;
    if(single<=mid)singleChange(2*k);
    else singleChange(2*k+1);
    nodes[k].w+=mod;
    //nodes[k].w=nodes[2*k].w+nodes[2*k+1].w;
}
void partSearch(int k)
{//区间查询
    if(nodes[k].l>=x&&nodes[k].r<=y)
    {
        ans+=nodes[k].w;
        return;
    }
    int mid=(nodes[k].l+nodes[k].r)/2;
    if(x<=mid)partSearch(k*2);//左
    if(y>mid)partSearch(k*2+1);//右
}
void partChange(int k)
{//区间修改(不用懒节点)
    if(nodes[k].l>=x&&nodes[k].r<=y)
    {
        if(nodes[k].l==nodes[k].r)
            nodes[k].w+=mod;//到达根节点
        else 
        {//结合建树和向下查询
            partChange(k*2);
            partChange(k*2+1);
            nodes[k].w=nodes[2*k].w+nodes[2*k+1].w;
        }
        return ;
    }
    int mid=(nodes[k].l+nodes[k].r)/2;
    if(y>mid)
        partChange(k*2+1);//左树
    if(x<=mid)
        partChange(k*2);//右树
    nodes[k].w=nodes[2*k].w+nodes[2*k+1].w;
}
void print (int n)
{
    for(int i=1;i<2*n;i++)
        cout<<nodes[i].w<<" | "<<nodes[i].l<<" - "<<nodes[i].r<<endl;
}
int main()
{
    int m,n;cin>>n>>m;
    build(1,n,1);
    //print(n);
    for(int i=0;i<m;i++)
    {
        int op;cin>>op;
        if(op==1)
        {
            cin>>x>>y>>mod;
            partChange(1);
            //print(n);
        }
        if(op==2)
        {
            cin>>x>>y;
            partSearch(1);
            cout<<ans<<endl;
            ans=0;
        }
    }
    return 0;
}

线段树(On2)

标签:typedef   sea   c++   turn   arch   +=   end   节点   for   

原文地址:https://www.cnblogs.com/tldr/p/10877719.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!