poj3468 A Simple Problem with Integers

第四棵线段树,其实推倒重写了好几遍。

说实话一点也不simple……

题目中写的增量c在-1e4到1e4之间,操作最多1e5,那c应该不会超过1e9才对,结果不用__int64存增量就会一直wa……

基本上还是线段树,开始建树的时候最好先把每个点的值接收进来再建,免得多更新一次。

然后用一个变量来存增量,一个变量来存区间和。

执行加操作的时候只要加到对应的区间就可以了,把增量存在该区间的增量上就返回,避免每次都加到根节点浪费时间。

执行查询操作的时候每次向下传递增量信息,查到对应区间返回即可。

变量名起的太长,自己看着都觉得恶心了……

1 #include <stdio.h>
2 typedef struct{
3 int left, right;
4 __int64 sum,add;
5 }SegTree;
6 SegTree segTree[350000];
7 __int64 value[100005];
8 __int64 createSegTree(int root, int left, int right){
9 int mid;
10 segTree[root].left = left;
11 segTree[root].right = right;
12 segTree[root].add = 0;
13 if(left == right){
14 segTree[root].sum = value[left];
15 return segTree[root].sum;
16 }
17 mid = left + right >> 1;
18 segTree[root].sum = createSegTree(root << 1, left, mid)
19 +createSegTree(root << 1 | 1, mid + 1, right);
20 return segTree[root].sum;
21 }
22
23 void updateSegTree(int root, int left, int right, __int64 num){
24 int mid;
25 if(left <= segTree[root].left && right >= segTree[root].right){
26 segTree[root].add += num;
27 segTree[root].sum += (segTree[root].right - segTree[root].left + 1) * num;
28 return;
29 }
30 if(segTree[root].add){
31 segTree[root << 1].sum += (segTree[root << 1].right - segTree[root << 1].left + 1)
32 * segTree[root].add;
33 segTree[root << 1 | 1].sum += (segTree[root << 1 | 1].right
34 - segTree[root << 1 | 1].left + 1) * segTree[root].add;
35 segTree[root << 1].add += segTree[root].add;
36 segTree[root << 1 | 1].add += segTree[root].add;
37 segTree[root].add = 0;
38 }
39 mid = segTree[root].left + segTree[root].right >> 1;
40 if(left <= mid)
41 updateSegTree(root << 1, left, right, num);
42 if(right > mid)
43 updateSegTree(root << 1 | 1, left, right, num);
44 segTree[root].sum = segTree[root << 1].sum + segTree[root << 1 | 1].sum;
45 }
46
47 __int64 querySegTree(int root, int left, int right){
48 int mid;
49 __int64 ans;
50 if(segTree[root].left == left && segTree[root].right == right)
51 return segTree[root].sum;
52 mid = segTree[root].left + segTree[root].right >> 1;
53 if(segTree[root].add){
54 segTree[root << 1].sum += (segTree[root << 1].right - segTree[root << 1].left + 1)
55 * segTree[root].add;
56 segTree[root << 1 | 1].sum += (segTree[root << 1 | 1].right
57 - segTree[root << 1 | 1].left + 1) * segTree[root].add;
58 segTree[root << 1].add += segTree[root].add;
59 segTree[root << 1 | 1].add += segTree[root].add;
60 segTree[root].add = 0;
61 }
62 if(right <= mid)
63 return querySegTree(root << 1, left, right);
64 else if(left > mid)
65 return querySegTree(root << 1 | 1, left, right);
66 else{
67 ans = querySegTree(root << 1, left, mid);
68 return ans + querySegTree(root << 1 | 1, mid + 1, right);
69 }
70 }
71 int main (void){
72 int root = 1;
73 int i,N,Q,left,right,num;
74 char order[2];
75 // freopen("in.txt","r",stdin);
76 while(~scanf("%d%d",&N,&Q)){
77 for(i = 1; i <= N; i++)
78 scanf("%I64d",&value[i]);
79 createSegTree(root,1,N);
80 for(i = 0; i < Q; i++){
81 scanf("%s",order);
82 if(order[0] == 'Q'){
83 scanf("%d%d",&left,&right);
84 if(left > right)
85 left ^= right ^= left ^= right;
86 printf("%I64d\n",querySegTree(root,left,right));
87
88 }
89 else{
90 scanf("%d%d%d",&left,&right,&num);
91 if(left > right)
92 left ^= right ^= left ^= right;
93 updateSegTree(root,left,right,num);
94 }
95 }
96 }
97 return 0;
98 }

原文地址:https://www.cnblogs.com/deadblue/p/2029480.html