• codevs 1082 线段树练习3


    1082 线段树练习 3

     

     时间限制: 3 s
     空间限制: 128000 KB
     题目等级 : 大师 Master
     
     
     
    题目描述 Description

    给你N个数,有两种操作:


    1:给区间[a,b]的所有数增加X


    2:询问区间[a,b]的数的和。

    输入描述 Input Description

    第一行一个正整数n,接下来n行n个整数,

    再接下来一个正整数Q,每行表示操作的个数,

    如果第一个数是1,后接3个正整数,

    表示在区间[a,b]内每个数增加X,如果是2,

    表示操作2询问区间[a,b]的和是多少。

    pascal选手请不要使用readln读入

    输出描述 Output Description

    对于每个询问输出一行一个答案

    样例输入 Sample Input

    3

    1

    2

    3

    2

    1 2 3 2

    2 2 3

    样例输出 Sample Output

    9

    数据范围及提示 Data Size & Hint

    数据范围

    1<=n<=200000

    1<=q<=200000

    mlgb ;

    a了一个星期终于过了;

    运行结果

    测试点#ask1.in 结果: 内存使用量: 232kB 时间使用量: 1ms 
    测试点#ask10.in 结果: 内存使用量: 13420kB 时间使用量: 399ms 
    测试点#ask2.in 结果: 内存使用量: 256kB 时间使用量: 1ms 
    测试点#ask3.in 结果: 内存使用量: 6380kB 时间使用量: 32ms 
    测试点#ask4.in 结果: 内存使用量: 6892kB 时间使用量: 176ms 
    测试点#ask5.in 结果: 内存使用量: 6764kB 时间使用量: 177ms 
    测试点#ask6.in 结果: 内存使用量: 13548kB 时间使用量: 365ms 
    测试点#ask7.in 结果: 内存使用量: 256kB 时间使用量: 1ms 
    测试点#ask8.in 结果: 内存使用量: 256kB 时间使用量: 1ms 
    测试点#ask9.in 结果: 内存使用量: 6252kB 时间使用量: 27ms 


    代码

    #include<cstdio>
    using namespace std;
    
    struct node {
        int l,r;
        long long int dis,flag;
    };
    struct node tree[800000];
    int n,m,q;
    int a,b,x1;
    
    void tree_up(int k)
    {
        tree[k].dis=tree[k*2].dis+tree[k*2+1].dis;
    }
    
    void tree_build(int k,int l,int r)
    {
        tree[k].l=l;
        tree[k].r=r;
        if(l==r)
        {
            scanf("%lld",&tree[k].dis);
            return;
        }
        int mid=(l+r)/2;
        tree_build(k*2,l,mid);
        tree_build(k*2+1,mid+1,r);
        tree_up(k);
    }
    
    void tree_down(int k)
    {
        if(tree[k].l==tree[k].r)
        {
            tree[k].flag=0;
            return;
        }
        tree[k*2].flag+=tree[k].flag;
        tree[k*2].dis+=(tree[k*2].r-tree[k*2].l+1)*tree[k].flag;
        tree[k*2+1].flag+=tree[k].flag;
        tree[k*2+1].dis+=(tree[k*2+1].r-tree[k*2+1].l+1)*tree[k].flag;
        tree[k].flag=0;
    }
    
    void tree_add(int k,int l,int r,int x)
    {
        if(tree[k].l==l&&tree[k].r==r)
        {
            tree[k].flag+=x;
            tree[k].dis+=(tree[k].r-tree[k].l+1)*x;
            tree_down(k);
            return ;
        }
        tree_down(k);
        int mid=(tree[k].l+tree[k].r)/2;
        if(l>mid) tree_add(k*2+1,l,r,x);
        else if(r<=mid) tree_add(k*2,l,r,x);
        else {
            tree_add(k*2,l,mid,x);
            tree_add(k*2+1,mid+1,r,x);
        }
        tree_up(k);
    }
    
    long long int tree_query(int k,int l,int r)
    {
        tree_down(k);
        if(tree[k].l!=tree[k].r) tree_up(k);
        if(tree[k].l==l&&tree[k].r==r)
            return tree[k].dis;
        int mid=(tree[k].l+tree[k].r)/2;
        if(l>mid) return tree_query(k*2+1,l,r);
        else if(r<=mid) return tree_query(k*2,l,r);
        else return tree_query(k*2,l,mid)+tree_query(k*2+1,mid+1,r);
    }
    
    int main()
    {
        scanf("%d",&n);
        tree_build(1,1,n);
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d",&q);
            switch(q){
                case 1:{
                    scanf("%d%d%d",&a,&b,&x1);
                    tree_add(1,a,b,x1);
                    break;
                }
                case 2:{
                    scanf("%d%d",&a,&b);
                    printf("%lld
    ",tree_query(1,a,b));
                    break;
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    [IOI1994][USACO1.5]数字三角形 Number Triangles
    和为给定数
    小凯的疑惑
    棋盘
    【2020NOI.AC省选模拟#2】C. 送分题
    【NOI OL #2】涂色游戏
    【NOI OL #3】小结
    【NOI OL #1】最小环
    【NOI OL #1】冒泡排序
    【NOI OL #1】序列
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/5905619.html
Copyright © 2020-2023  润新知