线段树(待续)

推荐博客:http://blog.csdn.net/metalseed/article/details/8039326

接下来是,对应的线段树的题目解析。

hdu 1166 排兵布阵(构造线段树,单点更新,查询区间和)

 1 #include <cstdio>
 2 #include <cstring>
 3 typedef long long LL;
 4 LL sum[50000 << 2];
 5 #define lson l,m,rt << 1
 6 #define rson m+1,r,rt << 1 | 1
 7 void pushup(int rt){sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}
 8 void build(int l,int r,int rt)
 9 {
10     if(l == r) {scanf("%d",&sum[rt]); return ;}
11     int m = (l + r) >> 1;
12     build(lson);
13     build(rson);
14     pushup(rt);
15 }
16 void update(int p,int add,int l,int r,int rt)
17 {
18     if(l == r) {sum[rt] += add;return ;}
19     int m = (l + r) >> 1;
20     if(p <= m)
21         update(p,add,l,m,rt << 1);
22     else
23         update(p,add,m+1,r,rt << 1 | 1);
24     pushup(rt);
25 }
26 LL query_sum(int ll,int rr,int l,int r,int rt)
27 {
28     if(ll <= l && rr >= r) return sum[rt];
29     LL tot = 0;
30     int m = (l + r) >> 1;
31     if(ll <= m)
32         tot += query_sum(ll,rr,l,m,rt << 1);
33     if(rr > m)
34         tot += query_sum(ll,rr,m+1,r,rt << 1 | 1);
35     return tot;
36 }
37 int main()
38 {
39     int T,n,x,y,p = 1;
40     char s[12];
41     scanf("%d",&T);
42     while(T--)
43     {
44         printf("Case %d:\n",p++);
45         scanf("%d",&n);
46         build(1,n,1);
47         while(~scanf("%s",s))
48         {
49             if(!strcmp(s,"End")) break;
50             scanf("%d%d",&x,&y);
51             if(!strcmp(s,"Query"))  {LL ans = query_sum(x,y,1,n,1);printf("%d\n",ans);}
52             if(!strcmp(s,"Add"))    update(x,y,1,n,1);
53             if(!strcmp(s,"Sub"))    update(x,-y,1,n,1);
54         }
55     }
56     return 0;
57 }

hdu 1754 I hate it(构造线段树,区间最大值查询,单点更新)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 typedef long long LL;
 6 LL MAX[200000 << 2];
 7 #define lson l,m,rt << 1
 8 #define rson m+1,r,rt << 1 | 1
 9 void pushup(int rt){MAX[rt] = max(MAX[rt << 1] , MAX[rt << 1 | 1]);}
10 void build(int l,int r,int rt)
11 {
12     if(l == r) {scanf("%d",&MAX[rt]); return ;}
13     int m = (l + r) >> 1;
14     build(lson);
15     build(rson);
16     pushup(rt);
17 }
18 void update(int p,int add,int l,int r,int rt)
19 {
20     if(l == r) {MAX[rt] = add;return ;}
21     int m = (l + r) >> 1;
22     if(p <= m)
23         update(p,add,l,m,rt << 1);
24     else
25         update(p,add,m+1,r,rt << 1 | 1);
26     pushup(rt);
27 }
28 LL query_max(int ll,int rr,int l,int r,int rt)
29 {
30     if(ll <= l && rr >= r) return MAX[rt];
31     LL ans = 0;
32     int m = (l + r) >> 1;
33     if(ll <= m)
34         ans = max(ans,query_max(ll,rr,l,m,rt << 1));
35     if(rr > m)
36         ans = max(ans,query_max(ll,rr,m+1,r,rt << 1 | 1));
37     return ans;
38 }
39 int main()
40 {
41     int n,m,x,y;
42     char ch;
43     while(~scanf("%d%d",&n,&m))
44     {
45         build(1,n,1);
46         for(int i=0;i<m;i++)
47         {
48             getchar();
49             scanf("%c%d%d",&ch,&x,&y);
50             if(ch == ‘Q‘)
51             {
52                 int ans = query_max(x,y,1,n,1);
53                 printf("%d\n",ans);
54             }
55             else
56                 update(x,y,1,n,1);
57         }
58     }
59     return 0;
60 }
时间: 2024-10-12 12:43:46

线段树(待续)的相关文章

P3373 【模板】线段树 2 (未完待续)

P3373 [模板]线段树 2 题解 样例 输入: 8 10 571373 5929 7152 8443 6028 8580 5449 8473 4237 2 4 8 4376 1 2 8 9637 2 2 6 7918 2 5 8 5681 3 2 8 1 1 5 6482 3 1 5 1 5 8 8701 2 5 8 7992 2 5 8 7806 输出 478836 562114 代码爆0  inginging #include<bits/stdc++.h> using namespac

讲解——线段树

   讲解--线段树 O.引例 A.给出n个数,n<=100,和m个询问,每次询问区间[l,r]的和,并输出. 一种回答:这也太简单了,O(n)枚举搜索就行了. 另一种回答:还用得着o(n)枚举,前缀和o(1)就搞定. 那好,我再修改一下题目. B.给出n个数,n<=100,和m个操作,每个操作可能有两种:1.在某个位置加上一个数:2.询问区间[l,r]的和,并输出. 回答:o(n)枚举. 动态修改最起码不能用静态的前缀和做了. 好,我再修改题目: C.给出n个数,n<=1000000,

线段树入门(I Hate It)

I Hate It Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问.当然,老师有时候需要更新某位同学的成绩. Input 本题目包含多组测试,请处理到文件结束. 在每个测试的第一行,

线段树——持续更新辣

一:线段树的基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结构的特性,基本能保持每个操作的复杂度为O(log n)性质:假设某节点对应的区间是[a,b],设c=(a+b)/2,则左子树对应的区间是[a,c],右子树对应的区间是[c+1,b],线段树空间复杂度为O(n); 2:维护点及点修改的线段树 (1)构造线段树 函数:build(int begin,int end,int node)

&#183;专题」 线段树

PKU暑期培训第一天,这次培训人很多,但是感觉打酱油的也不少,不知道大牛有多少. 第一天都是讲线段树的,课件的话和往常一样,没什么变化. 具体的话,讲了线段树和树状数组.线段树的话讲了单点更新,成段更新,扫描线已经离散化. 然后随便提了提树状数组.估计明天再讲一点点,然后接着是讲并查集,多串匹配什么的. 线段树的题目我做得很少,以前看过HH大神的模板,想模仿来着,其实也没什么理解. 重新理解一下线段树吧. 线段树的用途,主要是维护区间问题,比如区间的单点更新操作,成段更新,扫描线等等.当然还有一

poj 2182 Lost Cows (线段树)

 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8838   Accepted: 5657 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'wate

线段树优化建图

建图时,当边数非常的多,连边就需要线段树优化复杂度.将 O(n2) 优化成 O(nlogn). 图来自生哥,非常感谢他. ? 2018/2/23 18:51:00 就这个样子 ? 2018/2/23 18:51:10 绿边容量INF ? 2018/2/23 18:51:17 红边容量1 ? 2018/2/23 18:51:39 蓝边是个节点 代码实现待续-- 原文地址:https://www.cnblogs.com/milky-w/p/8463205.html

浅谈线段树 (例题:[USACO08FEB]酒店Hotel)By cellur925

今天我们说说线段树. 我个人还是非常欣赏这种数据结构的.(逃)因为它足够优美,有递归结构,有左子树和右子树,还有二分的思想. emm这个文章打算自用,就不写那些基本的操作了... 1° 简单的懒标记(仅含加法) 当我们进行区间修改(比如同时加上一个数)时,我们现在也许暂时不用它,可以当需要用的时候再改.这个时候我们就需要做个标记,这个标记就是懒标记,$lazy$.如果在后续的指令中需要从p向下递归,我们这时候检查它是否有标记.若有,就按照标记更新两个子节点,同时为子节点增加标记,清除p的标记.

[poj2104]可持久化线段树入门题(主席树)

解题关键:离线求区间第k小,主席树的经典裸题: 对主席树的理解:主席树维护的是一段序列中某个数字出现的次数,所以需要预先离散化,最好使用vector的erase和unique函数,很方便:如果求整段序列的第k小,我们会想到离散化二分和线段树的做法, 而主席树只是保存了序列的前缀和,排序之后,对序列的前缀分别做线段树,具有差分的性质,因此可以求任意区间的第k小,如果主席树维护索引,只需要求出某个数字在主席树中的位置,即为sort之后v中的索引:若要求第k大,建树时反向排序即可 1 #include