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 }

另外,原数组的类型最好要用long long


后记:

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

 

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