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
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 ",MyTree.query(MyTree.root, buffer[0], buffer[1])); 126 } 127 } 128 return 0; 129 }
另外,原数组的类型最好要用long long
后记:
一个神奇的问题:原数组int过不了,改成long long提交一次,过了,接着改成int,就Accepted