[HDU 1166 敌兵布阵] 线段树 或 树状数组


 1 #include<iostream>
2 #include<cstdio>
3 #include<memory.h>
4 using namespace std;
5 int n,C[50005];
6 //--------------------------
7 int lowbit(int x){
8 return x&-x;
9 }
10 int sum(int x){
11 int ret=0;
12 while(x>0){
13 ret+=C[x];
14 x-=lowbit(x);
15 }
16 return ret;
17 }
18 void add(int x,int d){
19 while(x<=n){
20 C[x]+=d;
21 x+=lowbit(x);
22 }
23 }
24 //--------------------------
25 int main(){
26 int T;
27 scanf("%d",&T);
28 int kases=1;
29 int i,j;
30 int a;
31 for(;kases<=T;kases++){
32 memset(C,0,sizeof(C));
33 scanf("%d",&n);
34 for(i=1;i<=n;i++){
35 scanf("%d",&a);
36 add(i,a);
37 }
38 char str[10];
39 printf("Case %d:\n",kases);
40 bool ok=1;
41 while(ok){
42 scanf("%s",str);
43 switch(str[0]){
44 case ‘Q‘:
45 scanf("%d%d",&i,&j);
46 printf("%d\n",sum(j)-sum(i-1));
47 break;
48 case ‘A‘:
49 scanf("%d%d",&i,&j);
50 add(i,j);
51 break;
52 case ‘S‘:
53 scanf("%d%d",&i,&j);
54 add(i,-j);
55 break;
56 case ‘E‘:
57 ok=0;
58 break;
59 default:break;
60 }
61 }
62 }return 0;
63 }


 1 #include<iostream>
2 #include<cmath>
3 using namespace std;
4 #define maxn 100005
5 class Node{
6 public:
7 int l,r;
8 int add;//附加值
9 int sum;
10 }node[maxn];
11 int getRight(int n){//获得满足2^x>=n的最小x[从0层开始,给编号获得层数]
12 return ceil(log10(n*1.0)/log10(2.0));
13 }
14 void build(int l,int r,int num){//输入区间[1,2^getRight(n)],num=1建树
15 if(l==r){
16 node[num].l=node[num].r=l;node[num].add=0;node[num].sum=0;
17 return;
18 }
19 node[num].l=l;node[num].r=r;node[num].add=0;node[num].sum=0;
20 build(l,(l+r)/2,num*2);
21 build((l+r)/2+1,r,num*2+1);
22 }
23 void add(int o,int l,int r,int v){//从o节点开始递归[只要调用时o=1即可]在区间[l,r]全部加v
24 if(l<=node[o].l && r>=node[o].r){//全覆盖[递归边界]
25 node[o].add+=v;
26 }else{
27 int M=node[o].l+(node[o].r-node[o].l)/2;
28 if(r<=M)add(o*2,l,r,v);
29 else if(l>M)add(o*2+1,l,r,v);
30 else{
31 add(o*2,l,M,v);
32 add(o*2+1,M+1,r,v);
33 }
34 }
35 //维护节点o
36 if(node[o].l!=node[o].r){//如果区间只是一个元素就不算
37 node[o].sum=node[2*o].sum+node[2*o+1].sum;
38 }else node[o].sum=0;
39 node[o].sum+=node[o].add*(node[o].r-node[o].l+1);
40 }
41
42 //这里addadd是从上往下这条路的累计addadd值[一同回溯记录这条路节点所有add之和,减少了一次回溯累加add值]
43 //初始时直接令其为0
44 int sum=0;
45 void ask(int o,int l,int r,int addadd){//从o节点开始递归[只要调用时o=1即可]在区间[l,r]的和
46 if(l<=node[o].l && r>=node[o].r){//全覆盖[递归边界]
47 sum+=(node[o].sum+addadd*(node[o].r-node[o].l+1));
48 }else{
49 int M=node[o].l+(node[o].r-node[o].l)/2;
50 if(r<=M)ask(o*2,l,r,node[o].add+addadd);
51 else if(l>M)ask(o*2+1,l,r,node[o].add+addadd);
52 else{
53 ask(o*2,l,M,node[o].add+addadd);
54 ask(o*2+1,M+1,r,node[o].add+addadd);
55 }
56 }
57 }
58 int main(){
59 int T;
60 scanf("%d",&T);
61 int kases=1;
62 int i,j;
63 int a;
64 for(;kases<=T;kases++){
65 int N;
66 scanf("%d",&N);
67 build(1,1<<getRight(N),1);
68 for(i=1;i<=N;i++){
69 scanf("%d",&a);
70 add(1,i,i,a);
71 }
72 char str[10];
73 printf("Case %d:\n",kases);
74 bool ok=1;
75 while(ok){
76 scanf("%s",str);
77 switch(str[0]){
78 case ‘Q‘:
79 scanf("%d%d",&i,&j);
80 sum=0;
81 ask(1,i,j,0);
82 printf("%d\n",sum);
83 break;
84 case ‘A‘:
85 scanf("%d%d",&i,&j);
86 add(1,i,i,j);
87 break;
88 case ‘S‘:
89 scanf("%d%d",&i,&j);
90 add(1,i,i,-j);
91 break;
92 case ‘E‘:
93 ok=0;
94 break;
95 default:break;
96 }
97 }
98 }return 0;
99 }

[HDU 1166 敌兵布阵] 线段树 或 树状数组,码迷,mamicode.com

时间: 2024-12-03 07:52:41

[HDU 1166 敌兵布阵] 线段树 或 树状数组的相关文章

hdu 1166 敌兵布阵 线段树 点更新

// hdu 1166 敌兵布阵 线段树 点更新 // // 这道题裸的线段树的点更新,直接写就可以了 // // 一直以来想要进线段树的坑,结果一直没有跳进去,今天算是跳进去吧, // 虽然十分简单,十分的水,继续加油 #include <algorithm> #include <bitset> #include <cassert> #include <cctype> #include <cfloat> #include <climits

HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)

思路:本题因为是点修改,所以我们可以用线段树或者是树状数组了.线段树的基本操作我在我的代码中会具体体现,关键是要理解下面这幅图,具体的思想大家可以去看看其他的资料 线段树AC代码: #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define N 50005 int num

HDU 1166 敌兵布阵 线段树

敌兵布阵 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视.中央情

HDU 1166 敌兵布阵(线段树单点更新,板子题)

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

hdu 1166 敌兵布阵 (线段树)

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

HDU 1166 敌兵布阵 //线段树单点更新

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

HDU 1166 敌兵布阵(线段树更新单节点模板):

Problem Description C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视.中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人

HDU - 1166 敌兵布阵 (线段树+单点修改,区间查询和)

C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于采取了某种先进的监测手段,所以每个工兵营地的人数C国都掌握的一清二楚,每个工兵营地的人数都有可能发生变动,可能增加或减少若干人手,但这些都逃不过C国的监视. 中央情报局要研究敌人究竟演习什么战术,所以Tidy要随时向Derek汇报某一段连续的工兵营地一共有多少人,例如Derek问:“Tidy,马上汇

HDU 1166 敌兵布阵 线段树单点更新求和

题目链接 中文题,线段树入门题,单点更新求和,建一棵树就可以了. #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #define N 50005 using namespace std; int data[N]; struct Tree { int l,r,sum; }tree[N*4]; void bui