线段树区间修改+查询区间和

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 int a[maxn];
 5 int sum[maxn<<2],exc[maxn<<2];
 6 void maintain(int k)
 7 {
 8     sum[k]=sum[k<<1]+sum[k<<1|1];
 9 }
10 void pushdown(int lenl,int lenr,int k)//标记下放,并更细节点信息
11 {
12     if(exc[k]){
13         exc[k<<1]=exc[k];
14         exc[k<<1|1]=exc[k];
15         sum[k<<1]=exc[k]*lenl;
16         sum[k<<1|1]=exc[k]*lenr;
17         exc[k]=0;
18     }
19 }
20 void build(int l,int r,int k)
21 {
22     if(l>r)
23         return ;
24     if(l==r){
25         sum[k]=a[l];
26         exc[k]=0;
27         return ;
28     }
29     int mid=(l+r)>>1;
30     build(l,mid,k<<1);
31     build(mid+1,r,k<<1|1);
32     maintain(k);
33 }
34 void change(int l,int r,int cl,int cr,int k,int newp)
35 {
36     if(l>r||cl>r||cr<l)
37         return ;
38     if(l>=cl&&r<=cr){
39         sum[k]=newp*(r-l+1);//在发现现在区域小于需要更新区域时
40         exc[k]=newp;//更新节点的结果,并增加延迟标记exc,用于之后的标记下放
41         return ;
42     }
43     int mid=(l+r)>>1;
44     pushdown(mid-l+1,r-mid,k);
45     change(l,mid,cl,cr,k<<1,newp);
46     change(mid+1,r,cl,cr,k<<1|1,newp);
47     maintain(k);
48 }
49 int query(int l,int r,int ql,int qr,int k)
50 {
51     if(l>r||ql>r||qr<l)
52         return 0;
53     if(l>=ql&&r<=qr)
54         return sum[k];
55     int mid=(l+r)>>1,ans=0;
56     pushdown(mid-l+1,r-mid,k);//每一层询问执行到这一步,为了下一次递归更新叶节点信息
57     if(mid>=l)
58         ans+=query(l,mid,ql,qr,k<<1);
59     if(mid<r)
60         ans+=query(mid+1,r,ql,qr,k<<1|1);
61     return ans;
62 }
63 int main()
64 {
65     ios::sync_with_stdio(false);
66     //freopen("in.txt","r",stdin);
67     int n,m,cmd,l,r,newp;
68     cin>>n;
69     for(int i=1;i<=n;++i)
70         cin>>a[i];
71     build(1,n,1);
72     cin>>m;
73     for(int i=0;i<m;++i){
74         cin>>cmd>>l>>r;
75         if(cmd){
76             cin>>newp;
77             change(1,n,l,r,1,newp);
78         }else
79             cout<<query(1,n,l,r,1)<<endl;
80     }
81     return 0;
82 }

模板:
模板的情况是询问区间里的所有元素的和,修改是将区间的元素全部改成newp。

原文地址:https://www.cnblogs.com/St-Lovaer/p/11828234.html

时间: 2024-10-14 09:47:27

线段树区间修改+查询区间和的相关文章

HDU 1166 敌兵布阵 【线段树-点修改--计算区间和】

敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 59891    Accepted Submission(s): 25331 Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营 地,Derek和Tidy的任务

线段树 单点更新查询 区间最大值 hdu 2795 Billboard

题意: 有一块h*w(1<=h,w<=10^9)的公告牌,需要在上面放n(n<=200000)个1*w[i]的公告,每个公告优先选可以放置的地方中最上的那行,同一行选最左的地方,依次输出每个公告放置在哪行,如果不能放置,输出-1. 可以把公告牌看作长为h的线段,构建一个线段树,每个节点存储区间的最大值,初始最大值为公告牌的宽度w.如果某区间的最大值大于当前公告的宽度,就可以放在该区间,由于公告优先放在上面,所以选区间的时候也应该先判断左边的区间可不可以,当在某个点放上公告后,该点的最大值

hdu1394线段树点修改,区间求和

Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of

线段树单点修改、区间修改、单点查询值、区间查询最大值、最小值、区间和之模板

毕生所学. 1 const int N = 2e5 + 10; 2 #define lson rt << 1 // == rt * 2 左儿子 3 #define rson rt << 1 | 1 // == rt * 2 + 1 右儿子 4 #define int_mid int mid = tree[rt].l + tree[rt].r >> 1 5 int a[N]; // 初始值 6 struct node { 7 int l, r; 8 ll val, laz

VK Cup 2015 - Round 1 E. Rooks and Rectangles 线段树 定点修改,区间最小值

E. Rooks and Rectangles Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/524/E Description Polycarpus has a chessboard of size n × m, where k rooks are placed. Polycarpus hasn't yet invented the rules of the game

hihocoder1070、1077线段树更新点查询区间

题目链接:http://hihocoder.com/problemset/problem/1070 http://hihocoder.com/problemset/problem/1077 我的代码: 1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 #define MAXN 1000005 7 8 int w[MAXN]; 9 10 struct segNode 11 { 12 int

线段树第二弹(区间更新)

上篇文章,我们介绍了线段树的基本概念和单点更新.区间查询,今天,我们来接着上次的线段树问题继续深入研究.在解决线段树问题的过程中,我们会遇到要求修改区间中某一元素值的问题,当然也可能会遇到要求修改一段子区间所有值的问题--即区间更新问题.回忆一下上篇文章单点更新的方法是,由叶节点逐级向上进行更新,此时更新一个节点值的时间复杂度为o(log n),(点击链接了解详情:线段树+RMQ问题第二弹),那么以这样的处理效率来进行区间更新结果会怎样?现在假设待更新区间数据的规模为 n ,那么就需要进行 n

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace

hdu 1754 I Hate It 线段树单点更新和区间求和

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 参照HH大牛写的额! Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多