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

线段树练习3

时间:2017-03-28 21:23:16      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:max   cst   script   输出   iostream   范围   build   hang   uil   

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

分类标签 Tags 

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,a,b,c,d;
const int maxn=100000;
struct nn
{
    int r,l,flag,dis;
}tree[maxn<<2];
void tree_up(int now)
{
    tree[now].dis=tree[now<<1].dis+tree[now<<1|1].dis;
}
void tree_down(int now)
{
    tree[now<<1].flag+=tree[now].flag;
    tree[now<<1|1].flag+=tree[now].flag;
    tree[now<<1].dis+=tree[now<<1].flag*(tree[now<<1].r-tree[now<<1].l+1);
    tree[now<<1|1].dis+=tree[now<<1|1].flag*(tree[now<<1|1].r-tree[now<<1].l+1);
    tree[now].flag=0;
    return;
} 
inline void tree_build(int now,int l,int r)
{
    tree[now].l=l;
    tree[now].r=r;
    if(l==r)
    {
        scanf("%d",&tree[now].dis);
        return ;
    }
    int mid=(tree[now].l+tree[now].r)>>1;
    tree_build(now<<1,l,mid);
    tree_build(now<<1|1,mid+1,r);
    tree_up(now);
 } 
inline void tree_change(int now,int l,int r,int x)
{
    if(tree[now].l==l&&tree[now].r==r)
    {
        tree[now].dis+=(tree[now].r-tree[now].l+1)*x;
        tree[now].flag+=x;
        return ;
    }
    if(tree[now].flag)
      tree_down(now);
    int mid=(tree[now].l+tree[now].r)>>1;
    if(l>mid)
      tree_change(now<<1|1,l,r,x);
    else if(r<=mid)
            tree_change(now<<1,l,r,x);
         else 
         {
             tree_change(now<<1,l,mid,x);
             tree_change(now<<1|1,mid+1,r,x);
         }
    tree_up(now);
}
inline int tree_chaxun(int now,int l,int r)
{
    if(tree[now].l==l&&tree[now].r==r)
      return tree[now].dis;
    if(tree[now].flag)
       tree_down(now);
    int mid=(tree[now].l+tree[now].r)>>1;
    if(l>mid)
        return tree_chaxun(now<<1|1,l,r);
    else if(r<=mid)
           return tree_chaxun(now<<1,l,r);
         else 
                return tree_chaxun(now<<1,l,mid)+tree_chaxun(now<<1|1,mid+1,r);
}
int main()
{
    scanf("%d",&n);
    tree_build(1,1,n);
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
     {
         scanf("%d",&a);
         if(a==1)
          {
              scanf("%d%d%d",&b,&c,&d);
              tree_change(1,b,c,d);
          }
        else 
          {
              scanf("%d%d",&b,&c);
              cout<<tree_chaxun(1,b,c);
          }
     }
     return 0;
}

 

线段树练习3

标签:max   cst   script   输出   iostream   范围   build   hang   uil   

原文地址:http://www.cnblogs.com/z360/p/6636884.html

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