[Poj 3321] Apple Tree [simulate DFS] [timestamp] [line segment Tree]

Source: Internet
Author: User

The code is short, concise, and hard to understand =.

Summary:

First, save the connected edge (insert ):

An array is used to simulate a one-way linked list. Therefore, each edge is saved twice;

The node of the linked list represents an edge with two values: the next branch of the apple tree and the last edge connected to the current node.

The "Address" of an edge is the sequence number added to the current Fork Point (because it is simulated using an array, that is, subscript addressing ).***

Because the number of each forks (except 1) is only an id, the list array is used for id addressing. the list value is the address of the last edge added to the id forks. * ** here it is very round = B attention order

Tree [list [id] is the last edge added to the id forks.

Note that because list is a global variable, it is automatically initialized to all 0, that is, the next of the first edge is 0.

Different edges of the same id forks are directly addressed using the next address of the linked list;

The edges of different id forks are directly addressed by id using the list array (only the last Edge ~ is found ~).

Then, each id is timestamp (make ):

Id addressing is also used here.

Use a struct array to store the [Entry, Exit] time corresponding to each id. This Code selects to exit and add one. The entry remains unchanged. Otherwise, it can be ~

 


This process simulates DFS.

Simply put;

1. always find the next node of the current node until the leaf node;

2. After arriving at the leaf node, record the timestamp. The input value = outbound value. The output value is ++. The previous forks are returned;

3. check whether there is an edge (that is, find the next node). If so, return Step 1 recursively.

If no, the input value = the minimum input value **, the output value = the maximum output value + + **, and the previous forks are returned. ** due to recursion, the value changes here are not easy to understand.

 


Make (0, 1) During the call. Therefore, the system will exit when step 3 is executed.

The following describes how to create a full line segment tree (each branch has an apple at the beginning ).

Find the interval corresponding to this id according to the tab. Just ask.

When you change the value, the single point or tab [id]. r will be fine (because it is the output value of the corresponding timestamp ).


 

# Include <cstdio >#include <cstring> using namespace std; # define maxn 110000 # define lson l, m, rt <1 # define rson m + 1, r, rt <1 | 1/*** except that 1 is the root node, other numbers can only be considered as IDs, and numbers have no guiding significance. A unique solution is available. **/int min (int a, int B) {return a + (B-a) & (B-a)> 31 ));} struct branch {// The branches are one-way int next, node;} tree [maxn <1]; // a tree consisting of branches struct Node {int l, r ;} tab [maxn]; // The int cnt, sum table composed of nodes; // count of branches // sum is the timestamp cursor int list [maxn], seg [maxn <2]; // seg is a line segment tree, lis T is ..? (Below) inline void insert (int fro, int to) // insert a branch {tree [cnt]. node = to; // id tree [cnt] of the target node. next = list [fro]; // The initial list [0] is 0, the subscripts of the branches corresponding to fro are used later. // the next of the branches stores the tree subscripts left over from the previous one. Therefore, the branches derived from fro can be found !!! List [fro] = cnt ++; // list uses id as the index .. the tree subscript is stored. // when you look at next, you should assume that "node" stores the node id, but itself is a branch, so next should be a pointer to the branches // while the next of the struct is unidirectional to the next node, so next here is also a unidirectional backtracking, only the previous branch} int make (int pre, int now) {// l is the entry timestamp, and r is the return timestamp. int p = list [now], mi = 2 * maxn, t; // list points to the last side while (p) {// The list array is initialized to 0. p = 0 indicates that the last edge t = tree [p] has been reached. node; // t pointing to the next node from now if (t! = Pre) mi = min (make (now, t), mi ); /// always input adjacent node parameters to make. // here, min is used to keep the timestamp at the time of entry, and mi is retained when recursion ends and returns, /// if the next son is found, mi will + + p = tree [p]. next; // If t = pre, stop recursion. p = tree [p]. next = 0 // since the previous insert call is continuous (a, B) (B,, /// if it reaches the "leaf branches", t = pre will appear !!! /// Of course, t! = Pre, you have to go back here after recursion. // at this time, find the next branch and continue... SOGA !! This simulates DFS !!! = B} mi = min (mi, sum); // when exiting, the left and right sides of the leaf nodes are equal to sum. /// when the leaf node is reached, mi will become larger here !!! Tab [now]. l = mi, tab [now]. r = sum ++; // the tree and list functions are limited to the timestamp creation. // at this point, the right endpoint is always ++, for leaf nodes, mi is used (the above mi takes the minimum value of INF and sum, which is sum). // if it is not a leaf node, return mi; // return mi. the mi is the same when I find my son !} Void update (int p, int l, int r, int rt) {if (l = r) {// XOR 1 seg [rt] ^ = 1; return ;} int m = (l + r)> 1; if (p <= m) update (p, lson); else update (p, rson ); seg [rt] = seg [rt <1] + seg [rt <1 | 1];} int query (int L, int R, int l, int r, int rt) {if (L <= l & R> = r) return seg [rt]; int m = (l + r)> 1, ret = 0; if (m> = L) ret + = query (L, R, lson); if (m <R) ret + = query (L, R, rson ); return ret;} void build (int l, int r, int rt) {if (l = r ){ Seg [rt] = 1; return;} int m = (l + r)> 1; build (lson), build (rson ); seg [rt] = seg [rt <1] + seg [rt <1 | 1]; // PushUp (rt) ;}int main () {int n; while (scanf ("% d", & n )! = EOF) {// if (n = 0) continue; int a, B; sum = cnt = 1; for (int I = 1; I <n; I ++) {scanf ("% d", & a, & B); insert (a, B); insert (B, );} make (); // The function is to concatenate branches into an apple tree and then traverse the DFS to obtain the timestamp build (1, n, 1 ); // The function should be to establish a line segment tree. This line segment tree is a standard summation line segment tree. It has nothing to do with the apple tree itself. // It only uses the DFS traversal of the apple tree to timestamp each node of the apple tree, then, the interval to be queried in the apple tree is replaced by a single point in the online segment tree, because the corresponding interval is not changed to int m, t; char s [2]; scanf ("% d", & m); while (m --) {scanf ("% s % d", s, & t ); if (s [0] = 'q') printf ("% d \ n", query (tab [t]. l, tab [t]. r, 1, n, 1); // The seg of the Line Segment tree is the number of apples in the segment. // The timestamp is stored in the tab, and the tab is addressing by id .. else {update (tab [t]. r, 1, n, 1) ;}} return 0 ;}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.