zoukankan      html  css  js  c++  java
  • 关于线段树

    其实线段树就是以空间来换时间的一种算法

    还是以题目来解释。

    题目大致内容是给你一个数列有n个数,然后有m个命令,1是让某个点增加一个值,0是询问某个区间的和。

    对于这道题,我们一开始可能是想到用循环,但想想,如果数据大了呢,时间就肯定会爆。

    所以我们用效率更高的算法,也就是线段数,它的复杂度是log级别的。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    struct node
    {
        int l,r;
        int v;
    }p[410000];//最好是题目数据的4倍
    int n,m,a[410000];
    void build(int id,int l,int r)//建树,id是节点的编号
    {
        p[id].l=l;
        p[id].r=r;
        if (l==r)
        {
            p[id].v=a[l];
        }
        else {
            int mid=(l+r)/2;
            build(id*2,l,mid);//递归建树(左儿子)
            build(id*2+1,mid+1,r);//(右儿子)
            p[id].v=p[id*2].v+p[id*2+1].v;
        }
        
    }
    void update(int id,int pos,int val)
    //更新,这里是单点更新,后面会介绍更加快的区间更新
    {
            if (p[id].l==p[id].r)
            {
                p[id].v+=val;
            }
            else 
            {
                int mid=(p[id].l+p[id].r)/2;
                if (pos<=mid) 
                update(id*2,pos,val);//同样,递归更新
                else 
                update(id*2+1,pos,val);
                p[id].v=p[id*2].v+p[id*2+1].v;
            }
    }
    int ask(int id,int l,int r)//询问
    {
        if (p[id].l==l&&p[id].r==r)
        return p[id].v;
        else 
        {
            int mid=(p[id].r+p[id].l)/2;
            if (r<=mid) return ask(id*2,l,r);
            else if (l>mid) return ask(id*2+1,l,r);
            else
                return ask(id*2,l,mid)+ask(id*2+1,mid+1,r);
        }
    }
    int main()
    {
        cin>>n;
        for (int i=1;i<=n;i++)
        cin>>a[i];
        build(1,1,n);
        cin>>m;
        for (int i=1;i<=m;i++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            if (a==1) 
            update(1,b,c);
            else printf("%d
    ",ask(1,b,c));
        }
        return 0;
    }

    初次写博客,如果有什么地方做的不到位,请在评论区点出,谢谢!

  • 相关阅读:
    ruby计算平方和开方
    Silverlight中DataGrid翻页或者滚动时CheckBox/RadioButton显示的问题
    bat文件设置ip地址
    gcc编译多线程
    TCP Nagle算法
    fork父子进程 信号处理
    Unix守护进程的创建示例
    inline内联函数
    volatile类型
    ioctl获取接口名称、IP地址、MAC地址、广播地址等
  • 原文地址:https://www.cnblogs.com/LWJ2333/p/7856314.html
Copyright © 2011-2022 走看看