hdu1166 单点更新

第一道线段树,对着学长给的板子敲,嘿嘿,纪念一下~~~

代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <string.h>
 5 #include <cmath>
 6 #include <cstdlib>
 7 #include <algorithm>
 8
 9 using namespace std;
10
11 const int maxn = 50000 + 10;
12 int a[maxn];
13
14 struct node
15 {
16     int left, right, sum;
17 } b[maxn*4];
18
19 void build(int left, int right, int i)
20 {
21     b[i].left = left;
22     b[i].right = right;
23     int mid = (left + right)/2;
24     if(left == right) {
25         b[i].sum = a[left];
26         return ;
27     }
28     build(left, mid, 2*i);
29     build(mid+1, right, 2*i+1);
30     b[i].sum = b[2*i].sum + b[2*i+1].sum;
31 }
32
33 void Add(int id, int num, int i)
34 {
35     if(b[i].left == b[i].right) {
36         b[i].sum += num;
37         return ;
38     }
39     else {
40         b[i].sum += num;
41         if(id <= b[2*i].right) Add(id, num, 2*i);
42         else Add(id, num, 2*i+1);
43     }
44 }
45
46 int Query(int left, int right, int i)
47 {
48     int mid;
49     if(left == b[i].left && right == b[i].right) {
50         return b[i].sum;
51     }
52     mid = (b[i].left + b[i].right)/2;
53     if(right <= mid) return Query(left, right, 2*i);
54     else if(left > mid) return Query(left, right, 2*i+1);
55     else return Query(left, mid, 2*i) + Query(mid+1, right, 2*i+1);
56 }
57
58 int main()
59 {
60     //freopen("test.in", "r", stdin);
61     char s[10];
62     int T, N, x, y;
63     scanf("%d", &T);
64     int t = T;
65     while(T--)
66     {
67         printf("Case %d:\n", t-T);
68         scanf("%d", &N);
69         for(int i = 1; i <= N; i++)
70             scanf("%d", &a[i]);
71         build(1, N, 1);
72         while(1) {
73             scanf("%s", s);
74             if(s[0] == ‘E‘) break;
75             scanf("%d%d", &x, &y);
76             if(s[0] == ‘Q‘) printf("%d\n", Query(x, y, 1));
77             else if(s[0] == ‘A‘) Add(x, y, 1);
78             else Add(x, -y, 1);
79         }
80     }
81     return 0;
82 }

hdu1166 单点更新,布布扣,bubuko.com

时间: 2024-12-16 06:16:35

hdu1166 单点更新的相关文章

Hdu1166单点更新线段树

入门线段树,单点更新.写了几遍,都是学着notonlysuccess写的. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list>

HDU1166(线段树单点更新区间查询)

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

HDU1166敌兵布阵(线段树单点更新)

线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN).而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩. [以下以 求区间最大值为例] 先看声明

线段树入门之单点更新

作者:zifeiy 标签:线段树 单点更新 :最最基础的线段树,只更新叶子节点,然后把信息用 push_up(int rt) 这个函数更新上来 HDU1166 敌兵布阵 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 线段树功能: update:单点增减: query:区间求和 #include <bits/stdc++.h> using namespace std; #define lson l, m, rt<<1 #def

POJ训练计划2828_Buy Tickets(线段树/单点更新)

解题报告 题意: 插队完的顺序. 思路: 倒着处理数据,第i个人占据第j=pos[i]+1个的空位. 线段树维护区间空位信息. #include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node { int x,v; } num[201000]; int sum[1000000],ans[201000]; void cbtree(int rt,int l,in

HDU2852_KiKi&#39;s K-Number(线段树/单点更新)

解题报告 题目传送门 题意: 意思很好理解. 思路: 每次操作是100000次,数据大小100000,又是多组输入.普通模拟肯定不行. 线段树结点记录区间里存在数字的个数,加点删点操作就让该点个数+1,判断x存在就查询[1,x]区间的个数和[1,x-1]的个数. 求x之后第k大的数就先确定小于x的个数t,第t+k小的数就是要求的. #include <iostream> #include <cstdio> #include <cstring> using namespa

hdu1754 单点更新

第二道线段树,哈哈哈,已经从区间求和萌萌哒变成求最大值,我是不是好无聊哦~~~~ 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int maxn = 200000 + 10; 10 int a[maxn]

POJ3264_Balanced Lineup(线段树/单点更新)

解题报告 题意: 求区间内最大值和最小值的差值. 思路: 裸线段树,我的线段树第一发.区间最值. #include <iostream> #include <cstring> #include <cstdio> #define inf 99999999 #define LL long long using namespace std; LL minn[201000],maxx[201000]; void update(LL root,LL l,LL r,LL p,LL

HDU1166_敌兵布阵(线段树/单点更新)

解题报告 题意: 略 思路: 线段树单点增减和区间求和. #include <iostream> #include <cstring> #include <cstdio> #define LL long long using namespace std; int sum[201000]; void update(int root,int l,int r,int p,int v) { int mid=(l+r)/2; if(l==r)sum[root]+=v; else