首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1082 线段树练习 3 区间查询与区间修改

1082 线段树练习 3 区间查询与区间修改

作者头像
attack
发布2018-04-13 15:17:33
5000
发布2018-04-13 15:17:33
举报

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 点此展开

在这里提醒大家一点

如果你用的是Dev-c++的5.92版本的话,用%lld输入可能会发生运行时错误

这时候如果你确保你的程序百分百对的话,可以直接提交

如果你不放心自己的程序,可以把%lld改成%I64d(I是大写i)进行调试,这样就不会出错了

但是切记

提交到洛谷上的时候一定要写%lld!!!!!!

否则全部WA而不是RE

切记切记

(ps:cena评测系统也是%lld)

我的代码基本是由函数构成的

写法比较通俗易懂

大家可以参考一下

再教大家一个小技巧:

如果你想要大批量的吧int改为long long int 的话

可以使#define 语句

然后用查找替换功能

注意查找的时候 查找的是 int+空格

否则你的printf会变得非常美观(手动滑稽)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define lglg long long int
 5 using namespace std;
 6 const lglg MAXN=200001;
 7 lglg n,m;
 8 lglg ans=0;
 9 struct node
10 {
11     lglg l,r,w,f;
12 }tree[MAXN*4];
13 inline void updata(lglg k)
14 {
15     tree[k].w=tree[k*2].w+tree[k*2+1].w;
16 }
17 inline void build(lglg k,lglg ll,lglg rr)
18 {
19     tree[k].l=ll;tree[k].r=rr;
20     if(tree[k].l==tree[k].r)
21     {
22         scanf("%lld",&tree[k].w);
23         return ;
24     }
25     lglg m=(ll+rr)/2;
26     build(k*2,ll,m);
27     build(k*2+1,m+1,rr);
28     updata(k);
29 }
30 inline void down(lglg k)
31 {
32     tree[k*2].f+=tree[k].f;
33     tree[k*2+1].f+=tree[k].f;
34     tree[k*2].w+=(tree[k*2].r-tree[k*2].l+1)*tree[k].f;
35     tree[k*2+1].w+=(tree[k*2+1].r-tree[k*2+1].l+1)*tree[k].f;
36     tree[k].f=0;
37 }
38 inline void interval_change(lglg k,lglg ll,lglg rr,lglg v)
39 {
40     if(tree[k].l>=ll&&tree[k].r<=rr)
41     {
42         tree[k].w+=(tree[k].r-tree[k].l+1)*v;
43         tree[k].f+=v;
44         return ;
45     }
46     if(tree[k].f)   down(k);
47     lglg m=(tree[k].l+tree[k].r)/2;
48     if(ll<=m)    interval_change(k*2,ll,rr,v);
49     if(rr>m)     interval_change(k*2+1,ll,rr,v);
50     updata(k);
51 }
52 inline void interval_ask(lglg k,lglg ll,lglg rr)
53 {
54     if(tree[k].l>=ll&&tree[k].r<=rr)
55     {
56         ans+=tree[k].w;
57         return ;
58     }
59     if(tree[k].f)    down(k);
60     lglg m=(tree[k].l+tree[k].r)/2;
61     if(ll<=m)
62         interval_ask(k*2,ll,rr);
63     if(rr>m)
64         interval_ask(k*2+1,ll,rr);
65 }
66 int main()
67 {
68     scanf("%lld",&n);
69     build(1,1,n);
70     scanf("%lld",&m);
71     while(m--)
72     {
73         lglg how;
74         scanf("%lld",&how);
75         if(how==1)//区间增加 
76         {
77             lglg x,y,v;
78             scanf("%lld%lld%lld",&x,&y,&v);
79             interval_change(1,x,y,v);
80         }
81         else//区间求和 
82         {
83             lglg x,y;
84             ans=0;
85             scanf("%lld%lld",&x,&y);
86             interval_ask(1,x,y);
87             printf("%lld\n",ans);
88         }
89     }
90     return 0;
91 }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-05-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1082 线段树练习 3
    • 分类标签 Tags 点此展开
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档