hdu 1166 敌兵布阵
题意:给定区间,每次修改一个点,查询区间的值。
做法:线段树。基本上就是poj 2352 Stars 的翻版。只是在建树的的过程有所变动。其他一模一样。
上代码:(基本上直接复制的poj 2352)
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cmath> 5 #include <algorithm> 6 #include <utility> 7 #include <cstring> 8 #include <fstream> 9 #include <string> 10 11 #define L(x) ( x << 1 ) 12 #define R(x) ( x << 1 | 1 ) 13 using namespace std; 14 15 const int MAXN=50004 ;//区间长度 16 const int MARK=-65535;//标记,必要时可以有多个 17 18 struct tnode 19 { 20 int mark,l,r;// 21 int mid(){ return (l+r)/2;} 22 int len(){ return (r-l);} 23 bool in(int ll,int rr) { return l >= ll && r <= rr; } 24 int sum; 25 //自行添加特殊数据:{lmax,rmax,max,num...} 26 } node[MAXN<<2]; 27 int a[MAXN],n; 28 void build(int f,int l,int r) 29 { 30 node[f].l=l;node[f].r=r; 31 node[f].mark=0; 32 if(node[f].len()==1) 33 { 34 node[f].sum=a[l]; 35 return; 36 } 37 int mid=node[f].mid(); 38 build(L(f),l,mid); 39 build(R(f),mid,r); 40 node[f].sum=node[L(f)].sum+node[R(f)].sum; 41 } 42 void pushDown(int f) 43 { 44 if(node[f].mark) 45 { 46 node[L(f)].mark+=node[f].mark; 47 node[L(f)].sum+=node[f].mark; 48 node[R(f)].mark+=node[f].mark; 49 node[R(f)].sum+=node[f].mark; 50 node[f].mark=0; 51 } 52 } 53 void update(int f,int l,int r,int value) 54 { 55 56 if(node[f].in(l,r)) 57 { 58 node[f].sum+=value; 59 node[f].mark+=value; 60 } 61 if(node[f].len()==1) 62 return; 63 pushDown(f); 64 int mid=node[f].mid(); 65 if(l<mid) update(L(f),l,r,value); 66 if(r>mid) update(R(f),l,r,value); 67 node[f].sum=node[L(f)].sum+node[R(f)].sum; 68 69 } 70 int query(int f,int l,int r) 71 { 72 73 /*if(node[f].l==l&&node[f].r==r) 74 return node[f].sum; 75 76 if(node[f].len()==1) 77 return 0; 78 79 pushDown(f); 80 int mid=node[f].mid(); 81 if(r<=mid) 82 return (query(L(f),l,r)); 83 else 84 if(l>=mid) 85 return query(R(f),l,r); 86 else 87 return query(L(f),l,mid)+query(R(f),mid,r); 88 */ 89 if(node[f].in(l,r)) 90 return node[f].sum; 91 pushDown(f); 92 int ans = 0; 93 int mid = node[f].mid(); 94 if( l < mid ) ans += query(L(f),l,r); 95 if( r > mid ) ans += query(R(f),l,r); 96 return ans; 97 } 98 99 int main(int argc, char* argv[]) 100 { 101 int t; 102 scanf("%d",&t); 103 for(int caset=1;caset<=t;caset++) 104 { 105 printf("Case %d:\n",caset); 106 int n; 107 scanf("%d",&n); 108 a[0]=0; 109 for(int i=1;i<=n;i++) 110 scanf("%d",&a[i]); 111 build(1,0,n+1); 112 char s[10]; 113 int x,y; 114 scanf("%s",s); 115 while(strcmp(s,"End")!=0) 116 { 117 scanf("%d%d",&x,&y); 118 if(strcmp(s,"Query")==0) 119 { 120 int tmp=query(1,x,y+1); 121 printf("%d\n",tmp); 122 } 123 else if(strcmp(s,"Add")==0) 124 update(1,x,x+1,y); 125 else if(strcmp(s,"Sub")==0) 126 update(1,x,x+1,-y); 127 scanf("%s",s); 128 } 129 } 130 }