[题解]poj.org Problem#3468

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

POJ Monthly--2007.11.25, Yang Yi

(来自http://poj.org/problem?id=3468)


  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

时间: 2024-11-17 07:25:30

[题解]poj.org Problem#3468的相关文章

[题解]poj Meteor Shower

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16313   Accepted: 4291 Description Bessie hears that an extraordinary meteor shower is coming; reports say that these meteors will crash into earth and destroy anything they hit. Anxious fo

[题解]poj 3368 Frequent values

Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16537   Accepted: 5981 Description You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indice

[题解]poj.org 2777 Count Color

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42472   Accepted: 12850 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem. There is a

Roadblocks http://poj.org/problem?id=3255

Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old home too quickly, because she likes the scenery along the way. She has decided to take the second-shorte

poj 1651 http://poj.org/problem?id=1651

http://poj.org/problem?id=1651Multiplication Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6188   Accepted: 3777 Description The multiplication puzzle is played with a row of cards, each containing a single positive integer. Dur

http://poj.org/problem?id=1330

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17818   Accepted: 9455 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each

POJ3278http://poj.org/problem?id=3278

http://poj.org/problem?id=3278 题目大意: m,n两个数m可+1, -1, *2变成n,需要经过几步 #include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> #include<queue> #define max(a, b)(a > b ? a : b) #define N 100010 using namespace s

[题解]poj 1274 The Perfect Stall(网络流)

二分匹配传送门[here] 原题传送门[here] 题意大概说一下,就是有N头牛和M个牛棚,每头牛愿意住在一些牛棚,求最大能够满足多少头牛的要求. 很明显就是一道裸裸的二分图最大匹配,但是为了练练网络流(做其它的题的时候,神奇地re掉了,于是就写基础题了)的最大流算法,就做做这道题. 每一个牛都可一看成是个源点,每一个牛棚都可以看成是个汇点,但是一个网络应该只有一个汇点和一个源点才对,于是构造一个连接每个牛的超级源点,一个连接每个牛棚的超级汇点,每条边的容量为1,然后最大流Dinic算法(其它最

我的第一篇题解——A+B Problem

背景 "任何一个伟大的思想,都有一个微不足道的开始."   --A+B Problem 题目描述 输入两个整数a,b,输出它们的和(|a|,|b|<=10^9). 输入输出格式 输入格式: 两个整数以空格分开 输出格式: 一个数,即两数之和 输入输出样例 输入样例#1: 20 30 输出样例#1: 50 思路 这是一道简单的入门题,放在这里是为了攒RP(顺便调试一下字体),直接上标程 标程 1 #include<cstdio> 2 /* 3 #include<i