线段树/hdu1166 敌兵布阵
题意
n个阵营一字排开,每个初始有a[i]个人。现有两种操作:
Q a b 查询[a,b]之间总人数并输出
A/S a b 在a号位添加/删除b个人
分析
单点更新,区域查询的线段树模板
Accepted Code
pascal版,zsc写的
1 Program hdu1166; 2 Const 3 Infile='hdu1166.in'; 4 Outfile='hdu1166.out'; 5 Type 6 jl=Record 7 l,r,w:Longint; 8 End; 9 Var 10 tree:Array[0..200000] Of jl; 11 a:Array[0..50000] OF Longint; 12 ch,ch1:Char; 13 n,z,t,i,x,y:Longint; 14 Procedure Build(x,l,r:Longint); 15 Var 16 mid:Longint; 17 Begin 18 tree[x].l:=l;tree[x].r:=r; 19 If (l=r) Then Begin 20 tree[x].w:=a[l]; 21 Exit; 22 End; 23 mid:=(l+r) Div 2; 24 If l<=mid Then Build(2*x,l,mid); 25 If mid <r Then Build(2*x+1,mid+1,r); 26 tree[x].w:=tree[2*x].w+tree[2*x+1].w; 27 End; 28 Function Query(x,l,r:Longint):Longint; 29 Var 30 anslchild,ansrchild,mid:Longint; 31 Begin 32 If (l<=tree[x].l)And(tree[x].r<=r) Then Begin 33 Query:=tree[x].w; 34 Exit; 35 End; 36 mid:=(tree[x].l+tree[x].r) Div 2; 37 anslchild:=0; 38 ansrchild:=0; 39 If l<=mid Then anslchild:=Query(2*x,l,r); 40 If mid <r Then ansrchild:=Query(2*x+1,l,r); 41 Query:=anslchild+ansrchild; 42 End; 43 Procedure Add(x,pos,w:Longint); 44 Var 45 mid:Longint; 46 Begin 47 If (tree[x].l=tree[x].r) Then Begin 48 tree[x].w:=tree[x].w+w; 49 Exit; 50 End; 51 mid:=(tree[x].l+tree[x].r) Div 2; 52 If pos<=mid Then Add(2*x,pos,w) Else Add(2*x+1,pos,w); 53 tree[x].w:=tree[2*x].w+tree[2*x+1].w; 54 End; 55 Begin 56 Assign(Input,Infile); 57 Assign(Output,Outfile); 58 Reset(Input); 59 Rewrite(Output); 60 Readln(t); 61 For z:=1 To t Do Begin 62 Writeln('Case ',z,':'); 63 Fillchar(tree,Sizeof(tree),0); 64 Readln(n); 65 For i:=1 To n Do Read(a[i]); 66 Build(1,1,n); 67 Readln; 68 Read(ch); 69 While (ch<>'E') Do Begin 70 Read(ch1); 71 While (ch1<>' ') Do Read(Ch1); 72 Readln(x,y); 73 If (Ch='Q') Then Writeln(Query(1,x,y)); 74 If (ch='A') Then Add(1,x,y); 75 If (ch='S') Then Add(1,x,-1*y); 76 Read(ch); 77 End; 78 Readln; 79 End; 80 Close(Input); 81 Close(Output); 82 End.
c++版
1 /* 2 PROBLEM:hdu1166 3 AUTHER:Rinyo 4 MEMO:线段树 5 */ 6 7 #include<cstdio> 8 #include<cstring> 9 using namespace std; 10 const int maxn(50030); 11 int ans; 12 struct node 13 { 14 int left,right,sum; 15 16 }tree[4*maxn]; 17 void maketree(int left,int right,int x) 18 { 19 tree[x].left=left;tree[x].right=right; 20 if (left==right) 21 { 22 scanf("%d",&tree[x].sum); 23 return; 24 } 25 int mid=(left+right)>>1; 26 maketree(left,mid,x<<1); 27 maketree(mid+1,right,x<<1|1); 28 tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum; 29 } 30 void query(int left,int right,int x,int l,int r) 31 { 32 if (l<=left && right<=r) 33 { 34 ans+=tree[x].sum; 35 return; 36 } 37 int mid=(left+right)>>1; 38 if (r<=mid) query(left,mid,x<<1,l,r); 39 else if (l>mid) query(mid+1,right,x<<1|1,l,r); 40 else 41 { 42 query(left,mid,x<<1,l,r); 43 query(mid+1,right,x<<1|1,l,r); 44 } 45 } 46 void update(int left,int right,int x,int pos,int add) 47 { 48 if (left==right) 49 { 50 tree[x].sum+=add; 51 return; 52 } 53 int mid=(left+right)>>1; 54 if (pos<=mid) update(left,mid,x<<1,pos,add); 55 else update(mid+1,right,x<<1|1,pos,add); 56 tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum; 57 } 58 int main() 59 { 60 freopen("1166.txt","r",stdin); 61 int t,n,cnt,a,b; 62 char str[10]; 63 cnt=1; 64 scanf("%d",&t); 65 while (t--) 66 { 67 scanf("%d",&n); 68 maketree(1,n,1); 69 printf("Case %d:\n",cnt++); 70 while (scanf("%s",str)) 71 { 72 if (str[0]=='E') break; 73 scanf("%d%d",&a,&b); 74 if (str[0]=='Q') 75 { 76 ans=0; 77 query(1,n,1,a,b); 78 printf("%d\n",ans); 79 } 80 else if (str[0]=='A') update(1,n,1,a,b); 81 else update(1,n,1,a,-b); 82 } 83 } 84 return 0; 85 }