线段树中对一段区间操作的方法----记录增量。详细实现见代码。
还要好好体会!
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 }
时间: 2024-10-23 14:25:09