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 }
View Code

 

 

 

 

posted @ 2016-07-21 16:52  happy_codes  阅读(169)  评论(0编辑  收藏  举报