A Simple Problem with Integers(线段树)
F - A Simple Problem with Integers
Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%lld & %llu
Description
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
Input
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Output
对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15
//自己写,又超时了,网上看了别人的才过的,在类里面要增加一个积累量这个数据,这样,增加命令的时候只要将特定区间积累量加起来并且num+总和,不必遍历到每一个叶节点,但是在查询时,还是要释放,因为,可能查的区间,在积累的这个区间只占一部分。
这样节约了时间,好像叫lazy的思想
1 #include <stdio.h> 2 #include <string.h> 3 4 struct 5 { 6 int l; 7 int r; 8 double num; 9 double Inc; 10 }shu[400000]; 11 12 void Init (int left,int right,int k) 13 { 14 shu[k].l=left; 15 shu[k].r=right; 16 shu[k].Inc=0; 17 if(left==right) 18 { 19 scanf("%lf",&shu[k].num); 20 return; 21 } 22 int mid=(left+right)/2; 23 Init(left,mid,2*k); 24 Init(mid+1,right,2*k+1); 25 shu[k].num=shu[2*k].num+shu[2*k+1].num; 26 } 27 28 void insert(int left,int right,double c,int k) 29 { 30 if (shu[k].l==left&&shu[k].r==right)//到某个区间 31 { 32 shu[k].Inc+=c; 33 return; 34 } 35 shu[k].num+=(right-left+1)*c; 36 int mid=(shu[k].l+shu[k].r)/2; 37 if (right<=mid) 38 insert(left,right,c,2*k); 39 else if (left>mid) 40 insert (left,right,c,2*k+1); 41 else 42 { 43 insert(left,mid,c,2*k); 44 insert(mid+1,right,c,2*k+1); 45 } 46 } 47 double query(int left,int right,int k) 48 { 49 if (shu[k].l==left&&shu[k].r==right)// 50 { 51 52 return shu[k].num+(shu[k].r-shu[k].l+1)*shu[k].Inc; 53 } 54 int mid=(shu[k].l+shu[k].r)/2; 55 if(shu[k].Inc!=0)//将这个区间的积累量释放 56 { 57 shu[k].num+=(shu[k].r-shu[k].l+1)*shu[k].Inc;//自己先加上 58 insert(shu[k].l,mid,shu[k].Inc,2*k); 59 insert(mid+1,shu[k].r,shu[k].Inc,2*k+1); 60 shu[k].Inc=0; 61 } 62 if (left>mid) return query(left,right,2*k+1); 63 else if (right<=mid) return query(left,right,2*k); 64 else 65 return query(left,mid,2*k)+query(mid+1,right,2*k+1); 66 67 } 68 69 int main() 70 { 71 int Q; 72 int all_p,a,b; 73 double c; 74 char comend; 75 while (scanf("%d%d",&all_p,&Q)!=EOF) 76 { 77 Init(1,all_p,1); 78 while (Q--) 79 { 80 getchar(); 81 scanf("%c",&comend); 82 scanf("%d%d",&a,&b); 83 84 if (comend=='Q') printf("%.0lf\n",query(a,b,1)); 85 if (comend=='C') 86 { 87 scanf("%lf",&c); 88 insert(a,b,c,1); 89 } 90 } 91 } 92 return 0; 93 }