Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18120 Accepted Submission(s): 7877
1 /* 功能Function Description: HDOJ-1166 树状数组插点问线 、线段树解法 2 开发环境Environment: DEV C++ 4.9.9.1 3 技术特点Technique: 4 版本Version: 5 作者Author: 可笑痴狂 6 日期Date: 20120808 7 备注Notes: 8 */ 9 10 /* 11 //代码一:----树状数组 12 #include<stdio.h> 13 #include<string.h> 14 15 int n; 16 int a[50005]; 17 18 int lowbit(int i) 19 { 20 return i&(-i); 21 } 22 23 void update(int i,int num) 24 { 25 while(i<=n) 26 { 27 a[i]+=num; 28 i+=lowbit(i); 29 } 30 } 31 32 int getsum(int i) 33 { 34 int sum=0; 35 while(i>0) 36 { 37 sum+=a[i]; 38 i-=lowbit(i); 39 } 40 return sum; 41 } 42 43 int main() 44 { 45 int T,i,j,m; 46 char cmd[10]; 47 scanf("%d",&T); 48 for(m=1;m<=T;++m) 49 { 50 printf("Case %d:\n",m); 51 memset(a,0,sizeof(a)); 52 scanf("%d",&n); 53 for(i=1;i<=n;++i) 54 { 55 scanf("%d",&j); 56 update(i,j); 57 } 58 while(scanf("%s",cmd)) 59 { 60 if(cmd[0]=='A') 61 { 62 scanf("%d%d",&i,&j); 63 update(i,j); 64 } 65 else if(cmd[0]=='Q') 66 { 67 scanf("%d%d",&i,&j); 68 printf("%d\n",getsum(j)-getsum(i-1)); 69 } 70 else if(cmd[0]=='S') 71 { 72 scanf("%d%d",&i,&j); 73 update(i,-j); 74 } 75 else 76 break; 77 } 78 } 79 return 0; 80 } 81 */ 82 83 //代码二:-------线段树 84 85 #include<stdio.h> 86 #define MAX 50000 87 88 struct node 89 { 90 int lc,rc; 91 int sum; //存放的是从lc到rc之间的总人数 92 }tree[MAX*3]; 93 94 void build(int s,int t,int T) 95 { 96 int mid=(s+t)>>1; 97 tree[T].lc=s; 98 tree[T].rc=t; 99 tree[T].sum=0; 100 if(s==t) 101 return; 102 build(s,mid,T<<1); 103 build(mid+1,t,(T<<1)|1); 104 } 105 106 void insert(int num,int add,int T) //编号为num的线段增加了add,从T开始查找,在含有num的线段中sum都加add 107 { 108 if(num<tree[T].lc||num>tree[T].rc) 109 return ; 110 else 111 { 112 tree[T].sum+=add; 113 if(tree[T].lc==tree[T].rc) 114 return; 115 if(num<=((tree[T].lc+tree[T].rc)>>1)) 116 insert(num,add,T<<1); 117 else 118 insert(num,add,(T<<1)|1); 119 } 120 } 121 122 int getsum(int s,int t,int T) //统计从s到t的总人数,从T开始查找知道找到该条线段为止 123 { 124 int mid=(tree[T].lc+tree[T].rc)>>1; 125 if(tree[T].lc==s&&tree[T].rc==t) 126 return tree[T].sum; 127 if(t<=mid) 128 return getsum(s,t,T<<1); 129 else if(s>mid) 130 return getsum(s,t,(T<<1)|1); 131 else 132 return getsum(s,mid,T<<1)+getsum(mid+1,t,(T<<1)|1); 133 } 134 135 136 int main() 137 { 138 int k,i,j,m,n,t; 139 char cmd[10]; 140 scanf("%d",&k); 141 for(m=1;m<=k;++m) 142 { 143 printf("Case %d:\n",m); 144 scanf("%d",&n); 145 build(1,n,1); 146 for(i=1;i<=n;++i) 147 { 148 scanf("%d",&t); 149 insert(i,t,1); 150 } 151 while(scanf("%s",cmd)) 152 { 153 if(cmd[0]=='A') 154 { 155 scanf("%d%d",&i,&j); 156 insert(i,j,1); 157 } 158 else if(cmd[0]=='Q') 159 { 160 scanf("%d%d",&i,&j); 161 printf("%d\n",getsum(i,j,1)); 162 } 163 else if(cmd[0]=='S') 164 { 165 scanf("%d%d",&i,&j); 166 insert(i,-j,1); 167 } 168 else 169 break; 170 } 171 } 172 return 0; 173 }