HDU 4680 about set Note (a day after all)

Source: Internet
Author: User
Problem descriptiontoday zhanyl (Sister Zhan as you know) es a task about set operation. Although she is very good at this task,
But you know she is very lazy so that she wants you to help her write a program to complete this task. Surly
Zhanyl is able to solve this question, but you know, she is just lazy...
Here is the problem, you are given n numbers, each number I has a value AI, initially they are in different set.
Following there are m operations/querys.
The following is 5 possible kinds of oprations/querys:
1 u v: Union the set U belongs to and the set V belongs.
2 u v: delete u from its original set and add it to the set V belongs.
3 u x: change the value of u to X. 1 <=x <= 109
4 U: query how many numbers you can choose most in set which u belongs to, so no three numbers can form a triangle.
5 u l r: query the GCD of the numbers between [L, R] In the set U belongs to, if there is no number between [L, R], you can suppose the answer is-1. 1 <= L <= r <= 109
Because zhanyl is a good person, so she guarantee 1 <= u, v <= n abve.
You need to tell zhanyl the answer to each query.


Inputthe first line of the input is a single integer T which is the number of test cases. Then comes the T test cases.
For each test case, the first line contains two integer N and m, n is the number of set initially, M is the number
Of Operations/querys.
Following line contains N integers, A1, A2,..., An, the value of I-th number.
Following M lines, each line is a operation or query.

Note that 1 <= n, m <= 105, 1 <= AI <= 109



Various operations are as follows. Big bare data structure, I wanted to think about it during the competition, but I haven't written this question about merging multiple trees for a long time. In addition, I am confused about the most critical heuristic merger, I think the complexity is not good, so I didn't think about it. Now I really regret it. I just blame myself for not being rigorous in thinking. If I think about it in a game, whether it can be AC or not, the passion of the competition. It took me a day to write all the functions of the splay tree for the first time. I didn't go to view those functions when I was too confident in debugging, and I had to read a lot of data from myself. Then I came to see it, just a little change, until all the bugs have been found (I think), handed in or TLE, I'm glad that this writing is not like writing the question in Tianjin 10, re has a long row (that is the first time to write the pointer splay), and many structure debugging operations are still easy, but due to a lot of details, as a result, the error I saw at the beginning was not modified, and then t .. Some highlights ::Tle continues .....Tle continues .....It's really worrying .....This day cannot be passed .....What to do ........Continue to bury yourself in the code .....Found !!!!Again, or tle .....MD, brute force .....Okay. Make some money first !!!! It's all about success...I have never been able to concentrate on teaching others to swim ,,,Returning to the dormitory in the evening, jie.com helped to run 100000 million data records, but it was impossible to run ..UnscientificThen, let's take a closer look. There's something silly ,,,,233333333333333333333333333333I am a peerless sb. I can't look straight at it...Then, I am angry with you and AC !!!!!!The idea of this question is very simple, just follow the simulation of the question. It is really a Data Structure question that should not be such a big bare question, so I should post a code... However, the Code is slightly subtle and confusing... Do not imitate

/*************************************** * ******* Author: wuyiqi created time: 8:24:44 File Name: HDU 4680.cpp ************************************** * ********/# pragma comment (linker, "/Stack: memory usage, 00000000") # include <cstring> # include <cstdio> # include <string> # include <iostream> using namespace STD; # define L x-> C [0] # define r x-> C [1] # define KT root-> C [1]-> C [0] const int maxn = 300010; const int Lim = 1000000000; int gcd (int A, int B) {if (a <0 | A> Lim) return B; if (B <0 | B> Lim) return a; return! B? A: gcd (B, A % B);} struct node {struct node * C [2], * Fa; int ID; int SZ; int GCD; int val; int who; bool D () {return fa-> C [0] = This;} void SETC (int d, node * s) {C [d] = s; s-> fa = This;} void up () {SZ = C [0]-> SZ + C [1]-> SZ + 1; GCD = gcd (C [0]-> GCD, C [1]-> gcd); GCD = gcd (GCD, Val);} void clear (node * null) {c [0] = C [1] = NULL;} node [maxn], * null = & node [0]; node * Q [maxn]; node * ID [maxn]; int Type; int N; int top; struct _ x_x _ {int type; node * root; void rotate (node * X, int f) {node * Y = x-> fa; y-> SETC (! F, x-> C [f]); X-> fa = Y-> fa; If (Y-> Fa! = NULL) Y-> fa-> SETC (! Y-> D (), x); X-> SETC (F, Y); y-> up ();} void splay (node * X, node * goal) {While (X-> Fa! = Goal) {If (X-> fa = goal) rotate (x, x-> D ()); else {int F = x-> fa-> D (); X-> D () = f? Rotate (X-> FA, f): Rotate (x ,! F); rotate (x, f) ;}} X-> up (); If (Goal = NULL) {root = x ;}} void RTO (int K, node * goal) {node * x = root; while (L-> SZ + 1! = K) {If (k <L-> SZ + 1) x = L; else {k-= L-> SZ + 1; X = r ;}} splay (x, goal);} node * new_node (node * Fa, int v) {node * x = & node [++ top]; X-> id = top; x-> C [0] = x-> C [1] = NULL; X-> SZ = 1; X-> val = V; X-> GCD = V; x-> fa = fa; Id [Top] = x; return X;} void Init (INT v) {root = new_node (null, V); type = ++ type; root-> who = type;} void del_root () {node * t = root; If (t-> C [1]! = NULL) {root = T-> C [1]; RTO (1, null); root-> C [0] = T-> C [0]; if (root-> C [0]! = NULL) Root-> C [0]-> fa = root;} else {root = root-> C [0];} root-> fa = NULL; if (root! = NULL) Root-> up ();} void Delete (node * X) {splay (x, null); del_root ();} void insert (node * X) {X-> clear (null); // before inserting a node, you cannot forget to clear its left and right sons insert (root, x); splay (x, null ); x-> who = type;} void insert (node * & X, node * Y) {If (x = NULL) {x = y; return ;} if (Y-> Val <= x-> Val) {insert (X-> C [0], y ); x-> C [0]-> fa = x;} else {insert (X-> C [1], y ); x-> C [1]-> fa = x;} X-> up ();} void change (int u, int v) {node * TM P = ID [U + 2 * n]; splay (TMP, null); del_root (); TMP-> val = V; insert (TMP );} node * find_succ (node * X, int v) {// equal or bigger than V if (x = NULL) return X; If (X-> val = V) return X; else if (X-> Val> V) {node * TMP = find_succ (X-> C [0], V); Return TMP = NULL? X: TMP;} else {return find_succ (X-> C [1], v) ;}} node * find_pre (node * X, int V) {// Strictly less than V if (x = NULL) return X; If (X-> Val <v) {node * TMP = find_pre (X-> C [1], V); Return TMP = NULL? X: TMP;} else {return find_pre (X-> C [0], v) ;}} int Gao () {If (root-> SZ <= 4) return root-> SZ-2; RTO (2, null); int A = root-> val; RTO (3, null); int B = root-> val; int ans = 2; while (true) {if (a + B> Lim) break; int c = find_succ (root, A + B)-> val; if (C> lim | C =-1) break; A = B; B = C; ans ++;} return ans;} int solve (INT l, int R) {node * pre = find_pre (root, L); node * succ = find_succ (root, R + 1); splay (PRE, null); splay (succ, root); Return KT-> GCD;} void Merge (_ x_x _ & tree) {int head = 0, tail = 0; tree. RTO (1, null); tree. RTO (tree. root-> SZ, tree. root); Q [++ tail] = tree. KT; while (Head <tail) {node * Fr = Q [++ head]; If (fr-> C [0]! = NULL) Q [++ tail] = fr-> C [0]; If (fr-> C [1]! = NULL) Q [++ tail] = fr-> C [1]; insert (FR); // after vomiting blood for a whole day, the above changes are returned, insert (root, fr); Fr-> who = type;} tree is not modified here. KT = NULL; tree. root-> C [1]-> up (); tree. root-> up () ;}} SPT [maxn]; void prepare () {null-> id = 0; null-> C [0] = NULL-> C [1] = NULL-> fa = NULL; null-> SZ = NULL-> val = 0; null-> GCD =-1; type = 0; Top = 0;} int main () {int T, M, CA = 1, op, U, V, l, r, X; scanf ("% d", & T); While (t --) {prepare (); scanf ("% d", & N, & M); For (INT I = 1; I <= N; I ++) {SPT [I]. init (-1); node * TMP = SPT [I]. new_node (null, Lim + 1); SPT [I]. insert (TMP) ;}for (INT I = 1, A; I <= N; I ++) {scanf ("% d", & ); node * TMP = SPT [I]. new_node (null, a); SPT [I]. insert (TMP) ;}int tot = 0; printf ("case # % d: \ n", CA ++); While (M --) {scanf ("% d", & OP); If (OP = 1) {scanf ("% d", & U, & V ); node * tmp1 = ID [U + 2 * n], * tmp2 = ID [V + 2 * n]; int tree1 = tmp1-> WHO; int tree2 = tmp2-> who; If (tree1 = tree2) continue; int sz1 = SPT [tree1]. root-> SZ; int sz2 = SPT [tree2]. root-> SZ; If (sz1> sz2) {SPT [tree1]. merge (SPT [tree2]);} else {SPT [tree2]. merge (SPT [tree1]) ;}} else if (OP = 2) {scanf ("% d", & U, & V ); node * tmp1 = ID [U + 2 * n], * tmp2 = ID [V + 2 * n]; int tree1 = tmp1-> WHO; int tree2 = tmp2-> who; SPT [tree1]. delete (tmp1); SPT [tree2]. insert (tmp1);} else if (OP = 3) {scanf ("% d", & U, & X ); node * TMP = ID [U + 2 * n]; int tree = TMP-> who; SPT [tree]. change (u, x);} else if (OP = 4) {scanf ("% d", & U ); node * TMP = ID [U + 2 * n]; int tree = TMP-> who; printf ("% d \ n", SPT [tree]. gao ();} else {scanf ("% d", & U, & L, & R ); node * TMP = ID [U + 2 * n]; int tree = TMP-> who; printf ("% d \ n", SPT [tree]. solve (L, R) ;}} 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.