首页 > 代码库 > poj3468

poj3468

线段树中对一段区间操作的方法----记录增量。详细实现见代码。

还要好好体会!

 1 //Accepted    6688K    1485MS    
 2 #include <cstdio>
 3 #include <cstring>
 4 #define imax 100005
 5 struct node
 6 {
 7     int l,r;
 8     __int64 add,sum;
 9 }f[imax*3];
10 int num[imax];
11 int n,m;
12 void build(int t,int l,int r)
13 {
14     f[t].l=l;
15     f[t].r=r;
16     f[t].add=0;
17     if (l==r)
18     {
19         f[t].sum=num[l];
20         return ;
21     }
22     int mid=(l+r)/2;
23     build(2*t,l,mid);
24     build(2*t+1,mid+1,r);
25     f[t].sum=f[2*t].sum+f[2*t+1].sum;
26 }
27 void Add(int t,int l,int r,int c)
28 {
29     if (f[t].l==l && f[t].r==r)
30     {
31         f[t].add+=c;
32         return ;
33     }
34     f[t].sum+=c*(r-l+1);
35     int mid=(f[t].l+f[t].r)/2;
36     if (r<=mid) Add(2*t,l,r,c);
37     else
38     {
39         if (l>mid) Add(2*t+1,l,r,c);
40         else
41         {
42             Add(2*t,l,mid,c);
43             Add(2*t+1,mid+1,r,c);
44         }
45     }
46 }
47 __int64 query(int t,int l,int r)
48 {
49     if (f[t].l==l && f[t].r==r)
50     {
51         return f[t].sum+f[t].add*(f[t].r-f[t].l+1);
52     }
53     int mid=(f[t].l+f[t].r)/2;
54     f[2*t].add+=f[t].add;
55     f[2*t+1].add+=f[t].add;
56     f[t].sum+=f[t].add*(f[t].r-f[t].l+1);
57     f[t].add=0;
58     if (r<=mid) return query(2*t,l,r);
59     else
60     {
61         if (l>mid) return query(2*t+1,l,r);
62         else
63         return query(2*t,l,mid)+query(2*t+1,mid+1,r);
64     }
65 }
66 int main()
67 {
68     while (scanf("%d%d",&n,&m)!=EOF)
69     {
70         for (int i=1;i<=n;i++)
71         scanf("%d",&num[i]);
72         build(1,1,n);
73         int x,y,c;
74         char ch[5];
75         for (int i=0;i<m;i++)
76         {
77             scanf("%s",ch);
78             if (ch[0]==Q)
79             {
80                 scanf("%d%d",&x,&y);
81                 printf("%I64d\n",query(1,x,y));
82             }
83             else
84             {
85                 scanf("%d%d%d",&x,&y,&c);
86                 Add(1,x,y,c);
87             }
88         }
89     }
90     return 0;
91 }
View Code