hihoCoder 1078 区间查询线段树

题面:

对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了小Ho:

假设货架上从左到右摆放了N种商品,并且依次标号为1到N,其中标号为i的商品的价格为Pi。小Hi的每次操作分为两种可能,第一种是修改价格——小Hi给出一段区间[L, R]和一个新的价格NewP,所有标号在这段区间中的商品的价格都变成NewP。第二种操作是询问——小Hi给出一段区间[L, R],而小Ho要做的便是计算出所有标号在这段区间中的商品的总价格,然后告诉小Hi。

那么这样的一个问题,小Ho该如何解决呢?

提示:推动科学发展的除了人的好奇心之外还有人的懒惰心!

输入

每个测试点(输入文件)有且仅有一组测试数据。

每组测试数据的第1行为一个整数N,意义如前文所述。

每组测试数据的第2行为N个整数,分别描述每种商品的重量,其中第i个整数表示标号为i的商品的重量Pi。

每组测试数据的第3行为一个整数Q,表示小Hi进行的操作数。

每组测试数据的第N+4~N+Q+3行,每行分别描述一次操作,每行的开头均为一个属于0或1的数字,分别表示该行描述一个询问和一次商品的价格的更改两种情况。对于第N+i+3行,如果该行描述一个询问,则接下来为两个整数Li, Ri,表示小Hi询问的一个区间[Li, Ri];如果该行描述一次商品的价格的更改,则接下来为三个整数Li,Ri,NewP,表示标号在区间[Li, Ri]的商品的价格全部修改为NewP。

对于100%的数据,满足N<=10^5,Q<=10^5, 1<=Li<=Ri<=N,1<=Pi<=N, 0

大致思路:

区间查询的模板题,直接套就好了。

代码:

 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;
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 }
时间: 2024-08-16 10:37:26

hihoCoder 1078 区间查询线段树的相关文章

HDU 1754 - I Hate It &amp; UVA 12299 - RMQ with Shifts - [单点/区间修改、区间查询线段树]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师

FOJ 2171 防守阵地 II 区间求和区间查询 线段树

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2171 题意: 给定n长序列,常数m,q个询问 对于每个询问x 1.求[x, x+m-1] 区间和 2.[x,x+m-1]区间的所有元素-1 线段树裸题,不知为何全用longlong会re,只能改成部分longlong #include<stdio.h> #include<string.h> #define ll long long #define LL int #define L(x) (x*

hihocoder #1079 : 离散化-线段树应用

#1079 : 离散化 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho在回国之后,重新过起了朝7晚5的学生生活,当然了,他们还是在一直学习着各种算法~ 这天小Hi和小Ho所在的学校举办社团文化节,各大社团都在宣传栏上贴起了海报,但是贴来贴去,有些海报就会被其他社团的海报所遮挡住.看到这个场景,小Hi便产生了这样的一个疑问——最后到底能有几张海报还能被看见呢? 于是小Ho肩负起了解决这个问题的责任:因为宣传栏和海报的高度都是一样的,所以宣传栏可以被视作

hihoCoder#1080 (线段树)

题目大意:线段树的区间更改与查询,但是涉及到两种区间修改方式,一是给区间中的数全部加上一个数,二是将一个区间全部置为同一个数,然后询问整个区间和. 题目分析:处理好set操作和add操作的先后顺序就OK了. 代码如下: # include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; const int N=100001; in

hihoCoder #1079 : 离散化 (线段树,数据离散化)

题意:有一块宣传栏,高一定,给出长度,再给出多张海报的张贴位置,问还能见到几张海报(哪怕有一点被看到)?假设海报的高于宣传栏同高. 思路:问题转成“给出x轴上长为L的一条线段,再用n条线段进行覆盖上去,最后还能看到及条线”.长度是0~L,即长度是L,进行离散化的时候,应该用1~L,每个数字表示一个单位长.还有就是按照提示所给的信息实现即可.步骤如下: (1)保存n个数据,做成pair,并将所有出现过的数字在另外找地方排序,去掉重复的,再将数据紧缩化处理,那么大小在1~max.再将紧缩化的数据与原

线段树 建树 单点修改 点点/区间查询

线段树(sgement tree)是一种分治思想的二叉树结构,用于在区间上进行信息统计.与按照二进制位进行区间划分的树状数组相比,线段树是一种更加通用的结构: 线段树的每个节点都代表一个区间. 线段树具有唯一的根节点,代表的区间是整个统计范围,如[1,n]. 线段树的每个叶节点都代表一个长度为1的元区间,如[x,x] 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度

hihoCoder #1078 : 线段树的区间修改(线段树区间更新板子题)

#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了小Ho: 假设货架上从左到右摆放了N种商品,并且依次标号为1到N,其中标号为i的商品的价格为Pi.小Hi的每次操作分为两种可能,第一种是修改价格——小Hi给出一段区间[L, R]和一个新的价格NewP,所有标号在这段区间中的商品的价格都变成NewP.第二种操作是询问——小Hi给出一段

hihoCode 1078 : 线段树的区间修改

#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了小Ho: 假设货架上从左到右摆放了N种商品,并且依次标号为1到N,其中标号为i的商品的价格为Pi.小Hi的每次操作分为两种可能,第一种是修改价格——小Hi给出一段区间[L, R]和一个新的价格NewP,所有标号在这段区间中的商品的价格都变成NewP.第二种操作是询问——小Hi给出一段

【算法系列学习】线段树vs树状数组 单点修改,区间查询 [kuangbin带你飞]专题七 线段树 A - 敌兵布阵

https://vjudge.net/contest/66989#problem/A 单点修改,区间查询 方法一:线段树 http://www.cnblogs.com/kuangbin/archive/2011/08/15/2139834.html 1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<cmath> 6 #