Http://acm.zju.edu.cn/onlinejudge/showProblem.do? Problemcode = 3018.
Question: there are up to 32768 points in a plane. Now there are two kinds of operations: 1: add n to some points, 2: Ask the sum of the number of points in a rectangle area
Analysis: This question looks like a line segment tree. If you want to do it offline, you may find it hard to handle it. But I cannot do it. Later, I YY a two-dimensional line segment tree, I have never written =. At first, I found that the space would blow up. I thought that many nodes do not need to be added, and then I can do it. The general idea is as follows:
Each node stores a rectangle, and the sum in the rectangle area. This node can be divided into four subnodes. Now, for the insert operation, the rectangle range is reduced continuously until it becomes a vertex, in this way, each vertex can generate a maximum of log (n) nodes (n is the number of X or Y after discretization), that is, the total number of nodes is 32768 * logn, which is completely feasible, the search result is similar to the line segment tree. The sum of the current region is returned every time you determine whether the current region covers the entire node, otherwise, recursion is followed by a child rectangle with overwrite... Okay, I haven't written it for a long time, and my presentation skills are getting worse. Let's take a look.CodeI feel like I have been practicing various trees for a while, and I am still comfortable writing such questions. ^_^
Code:
/** Head files */# include <cstdlib> # include <cctype> # include <cstring> # include <cstdio> # include <cmath> # include <algorithm> # include <cassert> # include <vector> # include <string> # include <iostream> # include <sstream> # include <map> # include <set> # include <queue> # include <stack> # include <fstream> # include <numeric> # include <iomanip> # include <bitset> # include <list> # include <stdexcept> # include <functional> # In Clude <utility> # include <ctime> using namespace STD;/** some operate */# define rep (I, n) for (INT I = 0; I <(n); ++ I) # define for (I, L, H) for (INT I = (l); I <= (h); ++ I) # define dwn (I, H, L) for (INT I = (h); I >=( L); -- I) # define foreach (E, X) for (_ typeof (X. begin () E = x. begin (); e! = X. end (); ++ e) # define CLR (ARR) memset (ARR, 0, sizeof (ARR) # define max3 (a, B, c) max (, max (B, c) # define max4 (A, B, C, D) max (a, B), max (c, d )) # define min3 (a, B, c) min (A, min (B, c) # define min4 (A, B, C, D) min (, b), min (c, d)/** some const */# define n 800100 # define PI ACOs (-1.0) # define oo 1000000000 # define loo quota limit 00ll # define EPS 1e-8/** some alias */typedef long ll; int DX [] = {0, 0,-}; int dy [] = {-,};/** Global variables * // ** some template names, just push Ctrl + J to get it in * // getint read optimization // manacher evaluate the longest echo substring // a small M combination of the pqueue priority queue // combk nelement Sequence and // maximum child matrix of pmatrix N points // suffixarray suffix array // sbtree Balance Tree struct retange {int X1, y1, X2, Y2; retange () {} retange (INT X1, int Y1, int X2, int Y2): x1 (X1), y1 (Y1 ), x2 (X2), Y2 (Y2) {} bool cover (const retange & A) const {If (x1>. x1 | X2 <. x2 | Y1>. y1 | Y2 <. y2) Return 0; return 1;} bool interset (const retange & A) const {If (x1>. x2 | Y1>. y2 |. x1> X2 |. y1> Y2) return 0; return 1;} bool OK () {return x1> = X2 & Y1> = Y2;} int MX () {return (X1 + x2)> 1;} int my () {return (Y1 + y2)> 1;} void RD (char * s) {sscanf (S, "% d", & X1, & X2, & Y1, & Y2) ;}; struct node {retange R; node * son [4]; ll sum;} tnode, * nil = & tnode; node mem [N], * c = MEM; node * Create (retange R) {C-> r = R; c-> sum = 0; Rep (I, 4) C-> son [I] = nil; return C ++;} void Update (INT X, int y, int N, node * now) {now-> sum + = N; while (1) {int MX = now-> r. mx (); int my = now-> r. my (); If (x <= mx) {If (Y <= My) {If (now-> son [0] = nil) now-> son [0] = create (retange (now-> r. x1, now-> r. y1, MX, my); now = now-> son [0];} else {If (now-> son [1] = nil) now-> son [1] = create (retange (now-> r. x1, My + 1, MX, now-> r. y2); now = now-> son [1] ;}} else {If (Y <= My) {If (now-> S On [2] = nil) now-> son [2] = create (retange (mx + 1, now-> r. y1, now-> r. x2, my); now = now-> son [2];} else {If (now-> son [3] = nil) now-> son [3] = create (retange (mx + 1, My + 1, now-> r. x2, now-> r. y2); now = now-> son [3] ;}} now-> sum + = N; If (now-> r. OK () break;} ll query (retange R, node * Now) {If (R. cover (now-> r) return now-> sum; ll ret = 0; rep (I, 4) if (now-> son [I]! = Nil & now-> son [I]-> r. interset (R) RET + = query (R, now-> son [I]); return ret;} Char s [333]; int main () {freopen ("A", "r", stdin); // freopen ("wa", "W", stdout); node * root = create (retange (0, 0, 20001,20001); retange R; int op, X, Y, N; while (gets (s) {If (s [0] = 'E ') {c = MEM; root = create (retange (, 20001,20001); continue;} If (s [0] = 'I') {op = 1; continue ;} if (s [0] = 'q') {op = 0; continue;} If (OP) {sscanf (S, "% d ", & X, & Y, & N); Update (X, Y, N, root);} else {R. rd (s); printf ("% LLD \ n", query (R, root) ;}} return 0 ;}