HDU ACM 4027 Can you answer these queries?(线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=4027
题意:有N条船,每条船都有各自的耐久度.有一种武器能攻击一个范围内的船.还要能计算一定范围内所有船剩余耐久的和.
耐久度去整数.耐久度的和不大于263
思路:每次更改都要更新范围内每条船的耐久度.
在攻击一定次数后,剩余耐久度肯定为1
所以结点中所有子节点耐久度均为1,则不需要继续更新
即发现Tree[o].sum == r - l + 1;
则不需要更新其子节点
1 #include <iostream> 2 #include <math.h> 3 using namespace std; 4 #define ol (o*2) 5 #define or (o*2+1) 6 const int MAX = 100000 + 10; 7 struct Node{ 8 int l; 9 int r; 10 __int64 sum; 11 }Tree[MAX*4]; 12 void BuildTree(int o,int l,int r){ 13 Tree[o].l = l; 14 Tree[o].r = r; 15 if(l == r){ 16 scanf("%I64d",&Tree[o].sum); 17 return; 18 } 19 int mid = (l + r)/2; 20 BuildTree(ol,l,mid); 21 BuildTree(or,mid+1,r); 22 Tree[o].sum = Tree[ol].sum + Tree[or].sum; 23 } 24 void Update(int o,int l,int r){ 25 if(Tree[o].sum == r - l + 1){//********** 26 return; 27 } 28 if(Tree[o].l == Tree[o].r){ 29 Tree[o].sum = (__int64)sqrt(1.0*Tree[o].sum); 30 return; 31 } 32 int mid = (Tree[o].l + Tree[o].r)/2; 33 if(l > mid){ 34 Update(or,l,r); 35 } 36 else{ 37 if(r <= mid){ 38 Update(ol,l,r); 39 } 40 else{ 41 Update(ol,l,mid); 42 Update(or,mid+1,r); 43 } 44 } 45 Tree[o].sum = Tree[ol].sum + Tree[or].sum; 46 } 47 __int64 Query(int o,int l,int r){ 48 if(Tree[o].l == l && Tree[o].r == r){ 49 return Tree[o].sum; 50 } 51 int mid = (Tree[o].l + Tree[o].r)/2; 52 if(l > mid){ 53 return Query(or,l,r); 54 } 55 else{ 56 if(r <= mid){ 57 return Query(ol,l,r); 58 } 59 else{ 60 return Query(ol,l,mid) + Query(or,mid+1,r); 61 } 62 } 63 } 64 int main(){ 65 int n; 66 int Case = 0; 67 while(cin>>n){ 68 memset(Tree,0,sizeof(Tree)); 69 Case++; 70 printf("Case #%d:\n",Case); 71 BuildTree(1,1,n); 72 int m; 73 cin>>m; 74 while(m--){ 75 int k,x,y; 76 cin>>k>>x>>y; 77 if(x > y){ 78 swap(x,y); 79 } 80 if(k == 0){ 81 Update(1,x,y); 82 } 83 else{ 84 printf("%I64d\n",Query(1,x,y)); 85 } 86 } 87 printf("\n"); 88 } 89 return 0; 90 }