kb-07专题--线段树-01-单点修改,区间查和
给定区间长度,然后给两个操作,单点增加值和单点减值,询问一个区间的人数和;(水)
代码如下:
1 /* 2 写的第一个线段树,丑; 3 */ 4 #include<iostream> 5 #include<cstdio> 6 #include<cstring> 7 #include<algorithm> 8 using namespace std; 9 typedef struct 10 { 11 int l,r; 12 int value; 13 }tr[100005];//长度是区间长度的四倍; 14 int n,a[50005]={0},ans=0; 15 void build(int i,int l,int r)//建树 16 { 17 tr[i].l=l; 18 tr[i].r=r; 19 if(l==r) 20 { 21 tr[i].value=a[l]; 22 return ; 23 } 24 build(i*2,l,(l+r)/2); 25 build(i*2+1,(l+r)/2+1,r); 26 tr[i].value=tr[i*2].value+tr[i*2+1].value; 27 } 28 void ADD(int i,int l,int x)//区间加值 29 { 30 if(tr[i].l==l&&tr[i].r==l) 31 { 32 tr[i].value+=x; 33 return ; 34 } 35 int t=i<<1; 36 if(l<=tr[t].r) 37 ADD(t,l,x); 38 t+=1; 39 if(l>=tr[t].l) 40 ADD(t,l,x); 41 tr[i].value=tr[i<<1].value+tr[(i<<1)+1].value; 42 } 43 void SUB(int i,int l,int x)//区间减值 44 { 45 if(tr[i].l==l&&tr[i].r==l) 46 { 47 tr[i].value-=x; 48 return ; 49 } 50 int t=i<<1; 51 if(l<=tr[t].r) 52 SUB(t,l,x); 53 t+=1; 54 if(l>=tr[t].l) 55 SUB(t,l,x); 56 tr[i].value=tr[i<<1].value+tr[(i<<1)+1].value; 57 } 58 void QUERY(int i,int l,int r)//区间查询寻; 59 { 60 if(tr[i].l==l&&tr[i].r==r) 61 { 62 ans+=tr[i].value; 63 return ; 64 } 65 i=i<<1; 66 if(l<=tr[i].r) 67 { 68 if(r<=tr[i].r) 69 QUERY(i,l,r); 70 else 71 QUERY(i,l,tr[i].r); 72 } 73 i+=1; 74 if(r>=tr[i].l) 75 { 76 if(l>=tr[i].l) 77 QUERY(i,l,r); 78 else 79 QUERY(i,tr[i].l,r); 80 } 81 } 82 int main() 83 { 84 int T,t=1; 85 cin>>T; 86 while(T--) 87 { 88 memset(a,0,sizeof(a)); 89 ans=0; 90 cin>>n; 91 for(int i=1;i<=n;i++) 92 { 93 scanf("%d",&a[i]); 94 } 95 printf("Case %d:\n",t++); 96 build(1,1,n); 97 char s[10]; 98 int x1,x2; 99 scanf("%s",s); 100 int k=0; 101 while(s[0]!='E') 102 { 103 scanf("%d%d",&x1,&x2); 104 if(s[0]=='A') 105 ADD(1,x1,x2); 106 else if(s[0]=='S') 107 SUB(1,x1,x2); 108 else if(s[0]=='Q') 109 { 110 QUERY(1,x1,x2); 111 printf("%d\n",ans); 112 ans=0; 113 } 114 scanf("%s",s); 115 } 116 } 117 return 0; 118 }