(线段树)hdoj1166-敌兵布阵
中央情報局要研究敵人究竟演習(xí)什么戰(zhàn)術(shù),所以Tidy要隨時向Derek匯報某一段連續(xù)的工兵營地一共有多少人,例如Derek問:“Tidy,馬上匯報第3個營地到第10個營地共有多少人!”Tidy就要馬上開始計算這一段的總?cè)藬?shù)并匯報。但敵兵營地的人數(shù)經(jīng)常變動,而Derek每次詢問的段都不一樣,所以Tidy不得不每次都一個一個營地的去數(shù),很快就精疲力盡了,Derek對Tidy的計算速度越來越不滿:"你個死肥仔,算得這么慢,我炒你魷魚!”Tidy想:“你自己來算算看,這可真是一項累人的工作!我恨不得你炒我魷魚呢!”無奈之下,Tidy只好打電話向計算機(jī)專家Windbreaker求救,Windbreaker說:“死肥仔,叫你平時做多點acm題和看多點算法書,現(xiàn)在嘗到苦果了吧!”Tidy說:"我知錯了。。。"但Windbreaker已經(jīng)掛掉電話了。Tidy很苦惱,這么算他真的會崩潰的,聰明的讀者,你能寫個程序幫他完成這項工作嗎?不過如果你的程序效率不夠高的話,Tidy還是會受到Derek的責(zé)罵的.?
Input第一行一個整數(shù)T,表示有T組數(shù)據(jù)。?
每組數(shù)據(jù)第一行一個正整數(shù)N(N<=50000),表示敵人有N個工兵營地,接下來有N個正整數(shù),第i個正整數(shù)ai代表第i個工兵營地里開始時有ai個人(1<=ai<=50)。?
接下來每行有一條命令,命令有4種形式:?
(1) Add i j,i和j為正整數(shù),表示第i個營地增加j個人(j不超過30)?
(2)Sub i j ,i和j為正整數(shù),表示第i個營地減少j個人(j不超過30);?
(3)Query i j ,i和j為正整數(shù),i<=j,表示詢問第i到第j個營地的總?cè)藬?shù);?
(4)End 表示結(jié)束,這條命令在每組數(shù)據(jù)最后出現(xiàn);?
每組數(shù)據(jù)最多有40000條命令?
Output對第i組數(shù)據(jù),首先輸出“Case i:”和回車,?
對于每個Query詢問,輸出一個整數(shù)并回車,表示詢問的段中的總?cè)藬?shù),這個數(shù)保持在int以內(nèi)。?
Sample Input
Sample Output
Case 1: 6 33 59線段樹的基礎(chǔ)應(yīng)用,init函數(shù)初始化樹各個結(jié)點,add,sub函數(shù)分別處理對線段樹上某葉子結(jié)點的值的更新,query函數(shù)返回查詢區(qū)間的值。
參考代碼
1 #include <iostream> 2 #include <queue> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 typedef long long ll; 8 typedef unsigned long long ull; 9 struct node 10 { 11 int left,right,mid; 12 int num; 13 }p[500005]; 14 void init(int a,int b,int n) 15 { 16 p[n].left=a; 17 p[n].right=b; 18 p[n].mid=(a+b)/2; 19 p[n].num=0; 20 if(a+1==b) 21 return; 22 init(a,(a+b)/2,2*n); 23 init((a+b)/2,b,2*n+1); 24 } 25 void add(int pos,int value,int n) 26 { 27 p[n].num+=value; 28 if(p[n].left+1==p[n].right) 29 return; 30 if(pos<p[n].mid) 31 add(pos,value,2*n); 32 else 33 add(pos,value,2*n+1); 34 } 35 void sub(int pos,int value,int n) 36 { 37 p[n].num-=value; 38 if(p[n].left+1==p[n].right) 39 return; 40 if(pos<p[n].mid) 41 sub(pos,value,2*n); 42 else 43 sub(pos,value,2*n+1); 44 } 45 int query(int a,int b,int n) 46 { 47 if(p[n].left==a&&p[n].right==b) 48 return p[n].num; 49 if(a<p[n].mid) 50 { 51 if(b<=p[n].mid) 52 return query(a,b,2*n); 53 else 54 return query(a,p[n].mid,2*n)+query(p[n].mid,b,2*n+1); 55 } 56 else 57 return query(a,b,2*n+1); 58 } 59 int t; 60 int N; 61 int s; 62 char rec[10]; 63 int main() 64 { 65 scanf("%d",&t); 66 for(s=1;s<=t;s++) 67 { 68 printf("Case %d:\n",s); 69 scanf("%d",&N); 70 init(1,N+1,1); 71 int i,tem,j; 72 for(i=1;i<=N;i++) 73 { 74 scanf("%d",&tem); 75 add(i,tem,1); 76 } 77 while(scanf("%s",rec)&&rec[0]!='E') 78 { 79 if(rec[0]=='A') 80 { 81 scanf("%d %d",&i,&j); 82 add(i,j,1); 83 } 84 else if(rec[0]=='S') 85 { 86 scanf("%d %d",&i,&j); 87 sub(i,j,1); 88 } 89 else if(rec[0]=='Q') 90 { 91 scanf("%d %d",&i,&j); 92 printf("%d\n",query(i,j+1,1)); 93 } 94 } 95 } 96 return 0; 97 }
?
?復(fù)習(xí)時重新寫的代碼1 #include <iostream> 2 #include<bits/stdc++.h> 3 #include <stack> 4 #include <queue> 5 #include <map> 6 #include <set> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <math.h> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned long long ull; 14 const int MAX=5e4+5; 15 int sum[MAX<<2]; 16 void init(int l,int r,int k) 17 { 18 if(l==r) 19 { 20 scanf("%d",&sum[k]); 21 return; 22 } 23 int mid=l+r>>1; 24 init(l,mid,2*k); 25 init(mid+1,r,2*k+1); 26 sum[k]=sum[2*k]+sum[2*k+1]; 27 } 28 void update(int lo,int num,int l,int r,int k) 29 { 30 if(l==r) 31 { 32 sum[k]+=num; 33 return; 34 } 35 int mid=l+r>>1; 36 if(lo<=mid) 37 update(lo,num,l,mid,2*k); 38 else 39 update(lo,num,mid+1,r,2*k+1); 40 sum[k]=sum[2*k]+sum[2*k+1]; 41 } 42 int query(int ql,int qr,int l,int r,int k) 43 { 44 if(l>=ql&&r<=qr) 45 return sum[k]; 46 int mid=l+r>>1; 47 if(qr<=mid) 48 return query(ql,qr,l,mid,2*k); 49 else if(ql>mid) 50 return query(ql,qr,mid+1,r,2*k+1); 51 else return query(ql,qr,l,mid,2*k)+query(ql,qr,mid+1,r,2*k+1); 52 } 53 int t,n; 54 char com[10]; 55 int lo,num; 56 int main() 57 { 58 scanf("%d",&t); 59 for(int i=1;i<=t;i++) 60 { 61 scanf("%d",&n); 62 init(1,n,1); 63 printf("Case %d:\n",i); 64 while(~scanf("%s",com)) 65 { 66 if(com[0]=='E') 67 break; 68 else 69 { 70 scanf("%d %d",&lo,&num); 71 if(com[0]=='A') 72 update(lo,num,1,n,1); 73 else if(com[0]=='S') 74 update(lo,-num,1,n,1); 75 else 76 printf("%d\n",query(lo,num,1,n,1)); 77 } 78 } 79 } 80 }
?
?轉(zhuǎn)載于:https://www.cnblogs.com/quintessence/p/6392448.html
總結(jié)
以上是生活随笔為你收集整理的(线段树)hdoj1166-敌兵布阵的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WebApi接口 - 响应输出xml和j
- 下一篇: js中cookie的操作