# poj 3468 A Simple Problem with Integers - 线段树

Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

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

Hint

The sums may exceed the range of 32-bit integers.

Source

j讲一下题目大意，就是有n个数和m个操作，操作有2种，一种是C还有一种是Q，C是将[a,b]这个区间内每一个数增加c，而Q是查询[a,b]这个区间的和

  1 /**
2  * poj.org
3  * Problem#3468
4  */
5 #include<iostream>
6 #include<cstdio>
7 using namespace std;
8 typedef long long ll;
9 ll *a;
10 /**
11  * 树节点
12  */
13 typedef class TreeNode{
14     private:
15         void init(){
16             left = NULL;
17             right= NULL;
18             sum  = 0;
19             state= 0;
20         }
21     public:
22         int from;            //区间的开始
23         int end;             //区间的结束
24         TreeNode *left;        //左子树
25         TreeNode *right;    //右子树指针
26         ll sum;                //这一段的和
27         ll state;            //延时标记，当非0表示有更新
28         TreeNode(){
29             init();
30         }
31         TreeNode(int from, int end){
32             init();
33             this->from = from;
34             this->end  = end;
35         }
36 }TreeNode;
37 /**
38  * 树结构
39  */
40 typedef class Tree{
41     public:
42         TreeNode* root;
43         Tree():root(NULL){}
44         Tree(int len){
45             root = build(root, 1, len);
46         }
47         void pushUp(TreeNode* node){
48             if(node->left != NULL && node->right != NULL)
49             node->sum = node->left->sum + node->right->sum;
50         }
51         void pushDown(TreeNode* node){
52
53             node->left->state += node->state;
54             node->left->sum += (node->left->end - node->left->from + 1) * node->state;
55
56             node->right->state += node->state;
57             node->right->sum += (node->right->end - node->right->from + 1) * node->state;
58
59             node->state = 0;
60
61         }
62         TreeNode* build(TreeNode* root,int from, int end){
63             if(from == end){
64                 root = new TreeNode(from, end);
65                 root->sum = a[from];
66                 return root;
67             }
68             root = new TreeNode(from, end);
69             int mid = (from + end)/2;
70             root->left = build(root->left, from, mid);
71             root->right = build(root->right, mid + 1, end);
72             pushUp(root);
73             return root;
74         }
75         void updata(TreeNode* now, int from, int end, ll data){
76
77             if(from <= now->from && now->end <= end ){
78                 now->state += data;
79                 now->sum += ( now->end - now->from + 1) * data;
80                 return ;
81             }
82             now->sum += (end - from + 1) * data;
83             if(now->state != 0) pushDown(now);
84             int mid = (now->from + now->end)/2;
85             if(end <= mid) updata(now->left, from, end, data);
86             else if(from > mid) updata(now->right, from, end,data);
87             else{
88                 updata(now->left, from, mid, data);
89                 updata(now->right, mid + 1, end, data);
90             }
91
92         }
93         ll query(TreeNode* now, int from, int end){
94
95             if(from <= now->from && now->end <= end ) return now->sum;
96             if(now->state != 0) pushDown(now);
97             int mid = (now->from + now->end)/2;
98             if(end <= mid) return query(now->left, from, end);
99             else if(from > mid) return query(now->right, from, end);
100             else{
101                 return (query(now->left, from, mid) +
102                     query(now->right, mid + 1, end));
103             }
104
105         }
106 }Tree;
107 int n,m;
108 Tree MyTree;
109 char c;
110 int buffer[3];
111 int main(){
112     scanf("%d%d",&n,&m);
113     a = new ll[(const int)(n + 1)];
114     for(int i = 1;i <= n;i++){
115         scanf("%lld",&a[i]);
116     }
117     MyTree = Tree(n);
118     for(int i = 1;i <= m;i++){
119         cin>>c;
120         if(c == 'C'){
121             scanf("%d%d%d",&buffer[0],&buffer[1],&buffer[2]);
122             MyTree.updata(MyTree.root, buffer[0], buffer[1], buffer[2]);
123         }else{
124             scanf("%d%d",&buffer[0],&buffer[1]);
125             printf("%lld\n",MyTree.query(MyTree.root, buffer[0], buffer[1]));
126         }
127     }
128     return 0;
129 }

一个神奇的问题:原数组int过不了，改成long long提交一次，过了,接着改成int，就Accepted

posted @ 2016-07-12 21:45  阿波罗2003  阅读(116)  评论(0编辑  收藏