zoukankan      html  css  js  c++  java
  • poj 3468

    题意  两种操作 1:区间更新c

                        2:问区间的和

          经典区间线段树

    #include <iostream>
    #include<stdio.h>
    using namespace std;
    const int N=100011;
    struct Node
    {
        int l,r;
        __int64 s,sum;
    }Tree[N*4];
    void Build(int root,int l,int r)
    {
        Tree[root].s=0;
        Tree[root].l=l;Tree[root].r=r;
        if(l==r)
        {
            scanf("%I64d",&Tree[root].sum);return ;
        }
        Build(root*2,l,(l+r)/2);
        Build(root*2+1,(l+r)/2+1,r);
        Tree[root].sum=Tree[root*2].sum+Tree[root*2+1].sum;
    }
    void pushdown(int root)
    {
        Tree[root].sum+=Tree[root].s*(Tree[root].r-Tree[root].l+1);
        Tree[root*2].s+=Tree[root].s;
        Tree[root*2+1].s+=Tree[root].s;
        Tree[root].s=0;
    }
    __int64 Query(int root,int l,int r)//查询 l-->r区间的和
    {
        if(Tree[root].l==l&&Tree[root].r==r)
            return (Tree[root].r-Tree[root].l+1)*Tree[root].s+Tree[root].sum;//节点的sum值保存的是 孩子节点的所有 lazy 与sum的值 而不保存当前节点的lazy值
        if(Tree[root].s)//在查询的时候向下推  
            pushdown(root);//查询的时候则必须pushdown与 区间覆盖恰恰相反;
        int mid=(Tree[root].l+Tree[root].r)/2;
        if(r<=mid)
            return Query(root*2,l,r);
        else if(l>mid)
            return Query(root*2+1,l,r);
        else return Query(root*2,l,mid)+Query(root*2+1,mid+1,r);
    }
    void Updata(int root,int l,int r,__int64 c)
    {
        if(Tree[root].l==l&&Tree[root].r==r)
        {
            Tree[root].s+=c;
            return ;
        }
        Tree[root].sum+=c*(r-l+1);//所过祖先节点 肯定包括当前要插入的区间  因此 不需要pushdown;采取了从上向下的更新方式;
        int mid=(Tree[root].l+Tree[root].r)/2;
        if(r<=mid)
             Updata(root*2,l,r,c);
        else if(l>mid)
            return Updata(root*2+1,l,r,c);
        else
        {
             Updata(root*2,l,mid,c);
             Updata(root*2+1,mid+1,r,c);
        }
    }
    int main()
    {
        char str[11];
        int n,m,a,b;
        __int64 d;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
    
            Build(1,1,n);
            while(m--)
            {
                scanf("%s",str);
                if(str[0]=='Q')
                {
                    scanf("%d%d",&a,&b);
                    printf("%I64d
    ",Query(1,a,b));
                }
                else
                {
                    scanf("%d%d%I64d",&a,&b,&d);
                    Updata(1,a,b,d);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Ubuntu20.04 安装AMD显卡驱动
    Ubuntu IBus RIME 输入法 配置小鹤双拼
    python time常用转换
    Linux 目录软链接
    MarkDown 插入图片 && Picture To Base64
    Bitmap 简介
    Linux 使用命令发送邮件
    Linux分区
    PyQt graphicsView自适应显示图像
    Python 图片转视频
  • 原文地址:https://www.cnblogs.com/zhangdashuai/p/4351488.html
Copyright © 2011-2022 走看看