(Hdu step 5.3.1) enemy deployment (line segment tree: Single Point update), hdu5.3.1
Question:
| Enemy army deployment |
| Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
| Total Submission (s): 312 Accepted Submission (s): 194 |
| |
Problem DescriptionC's dead enemy country A is conducting military exercises during this time, so Derek and Tidy of country C are busy again. Country A has deployed N barracks along the coastline. Derek and Tidy are responsible for monitoring the activities of these barracks. Some advanced monitoring means have been adopted, so the number of people in each engineer camp is clearly understood by country C. The number of people in each engineer camp may change, and the number of workers may increase or decrease, but none of these can escape the surveillance of country C. The Central Intelligence Agency needs to study what tactics the enemy actually exercises, so Tidy must report to Derek at any time the total number of people in a continuous barracks. For example, Derek asked: "Tidy, report on the total number of people from 3rd camps to 10th camps!" Tidy is about to calculate the total number of people in this section and report it immediately. However, the number of people in the enemy barracks often changes, and Derek asks for different segments each time. Therefore, Tidy has to go to the camp one by one each time and is exhausted soon, derek is getting increasingly dissatisfied with Tidy's computing speed: \ "you are a fat boy. It's so slow. I'll fry you!" Tidy thought, "you can calculate it yourself. This is really a tiring job! I wish you fired my squid !" In desperation, Tidy had to call Windbreaker, a computer expert, for help. Windbreaker said: "Fat Boy, I want you to do more acm questions and read more algorithm books. Now I have a bitter taste !" Tidy says: \ "I know the error... \\\\\\\ ", But Windbreaker has hung up. Tidy is very upset. In this case, he will actually crash. Smart readers, can you write a program to help him complete the job? However, if your program is not efficient enough, Tidy will still be scolded by Derek. |
The first line of Input is an integer T, indicating that T groups of data exist. The first line of each group of data is a positive integer N (N <= 50000), indicating that the enemy has N barracks, followed by N positive integers, the I positive integer ai represents an ai individual (1 <= ai <= 50) at the beginning of the I barracks ). Next, each line contains a command in four forms: (1) Add I j, I and j are positive integers, indicating that j individuals are added to camp I (j cannot exceed 30) (2) Sub I j, I and j are positive integers, indicating that j individuals are reduced in camp I (j cannot exceed 30 ); (3) Query I j, I and j are positive integers. I <= j indicates the total number of camp I to j; (4) End indicates the End. This command appears at the End of each group of data; Each group of data can contain a maximum of 40000 commands. |
Output For group I data, first output "Case I:" And press Enter, For each Query, output an integer and press enter to indicate the total number of members in the Query segment. The maximum number is 1000000. |
Sample Input1101 2 3 4 5 6 7 8 9 10Query 1 3Add 3 6Query 2 7Sub 10 2Add 6 3Query 3 10End |
Sample OutputCase 1:63359 |
| AuthorWindbreaker |
| |
| RecommendEddy |
Question Analysis:
Line Segment tree. Single point update.
The Code is as follows:
/** A1.cpp ** Created on: March 9, 2015 * Author: Administrator */# include <iostream> # include <cstdio> using namespace std; const int maxn = 50001; // maximum number of nodes struct node {// int left of the tree segment node; // int right of the left node of the interval; // int sum of nodes in the interval; // The value of the entire interval/*** is used to calculate the median of the interval */int mid () {return (left + right)/2;} tree [maxn * 4]; // The number of nodes in the line segment tree is four times the number of common array nodes int ans; // used to store the interval value after the query/*** line segment tree constructor * left: left endpoint * right: right endpoint * rt: ID of the node in the range */Void buildtree (int left, int right, int rt) {tree [rt]. left = left; // left node tree of the node in this interval [rt]. right = right; // The right node of the node in this interval if (left = right) {// if the current node records only one value in the interval scanf ("% d ", & tree [rt]. sum); // copy return directly to the current node;} // otherwise, recursively construct the left and right subtree int mid = tree [rt]. mid (); buildtree (left, mid, rt * 2); buildtree (mid + 1, right, rt * 2 + 1 ); // The range value of the current node = the range value of the left child + the range value of the right child tree [rt]. sum = tree [rt * 2]. sum + tree [rt * 2 + 1]. sum;}/*** in the range node r T: query the range value of [L, R]. left is the left endpoint of the rt of the interval node, and * right is the right endpoint of the interval node */void query (int left, int right, int rt, int L, int R) {// if the range to be searched contains the concise point of the entire range found currently, if (L <= left & right <= R) {ans + = tree [rt]. sum; // Add the current range value return;} // otherwise, search for int mid = tree [rt] recursively Based on the left and right subtree. mid (); if (R <= mid) {query (left, mid, rt * 2, L, R);} else if (mid <L) {query (mid + 1, right, rt * 2 + 1, L, R);} else {query (left, mid, rt * 2, L, R ); query (mid + 1, right, rt * 2 + 1, L, R) ;}}/*** add */void update (int left, int right, int rt, int pos, int add) {// if the target node is found if (left = right) {tree [rt]. sum + = add; // add the add directly to the target node return;} // If the left and right subtree are not used to Recursively search for int mid = tree [rt]. mid (); if (pos <= mid) {update (left, mid, rt * 2, pos, add);} else {update (mid + 1, right, rt * 2 + 1, pos, add);} // Finally, update the range value of the current node = the range value of the left child + the range value of the right child tree [rt]. sum = tree [rt * 2]. sum + Tree [rt * 2 + 1]. sum;} int main () {int t; scanf ("% d", & t); int k; for (k = 1; k <= t; ++ k) {printf ("Case % d: \ n", k); int n; scanf ("% d", & n); buildtree (1, n, 1 ); char str [10]; while (scanf ("% s", str )! = EOF) {if (str [0] = 'E') {break;} if (str [0] = 'A') {int A, B; scanf ("% d", & a, & B); update (1, n, 1, a, B );} else if (str [0] ='s ') {int a, B; scanf ("% d", & a, & B); update (1, n, 1, a,-B);} else if (str [0] = 'q') {ans = 0; int left; int right; scanf ("% d", & left, & right); query (1, n, 1, left, right); printf ("% d \ n ", ans) ;}}return 0 ;}