hdu 4680 About set 小記(畢竟是一天的時光啊)

來源:互聯網
上載者:User
Problem DescriptionToday Zhanyl (sister Zhan as you know) receives 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 to.
2 u v: Delete u from its original set and add it to the set v belongs to.
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 above.
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 



 各種操作如上。大裸資料結構啊,比賽的時候想敲的,不過很長時間沒寫這種多顆樹合并的題,而且有一個最關鍵的啟發學習法合并的地方想歪了,認為複雜度不行,就沒敲,現在想想還真是後悔,只怪自己的思維還不夠嚴謹,要是在比賽中敲,不管能不能AC,都會比賽後敲來的激情啊。好歹花了一天時間,第一次全部手寫splay樹的所有函數,debug的時候過於自信就沒去看那幾個函數,而且還過了自己出的很多資料,後來看到了,就一點點改,一直到所有的bug都找到了(我認為的),交上去還是TLE,比較慶幸的是這次寫沒有像寫10天津那個題一樣,RE了好長一排(那是第一次寫指標splay),很多結構調試起來還是輕鬆的,但是由於種種細節過多,導致我一開始就看出來的錯誤有一個地方沒有修改好,然後就一直T。。一些花絮::TLE持續中。。。。。TLE持續中。。。。。實在是好憂桑啊。。。。。這日子沒法過了。。。。。怎麼辦怎麼辦。。。。。。。。繼續埋頭看代碼。。。。。找到了!!!!再來一發,還是TLE。。。。。MD,爆粗口了。。。。。好吧,先去賺點錢吧!!!!都是正事啊。。。教別人遊泳的時候一直無法專心,,,,,明明沒錯啊,,,晚上回到寢室,傑哥幫忙跑了一發100000的資料,竟然跑不出來。。這不科學然後仔細一看,有個地方寫傻了,,,,233333333333333333333333333333我乃絕世大sb,不能直視啊。。。然後怒交一發,AC了!!!!!!這個題思路很簡單的,就按照題目告訴的類比就好了,真正好的資料結構題不該是這種大裸的題吧,,,還是貼個代碼吧。。。不過代碼略微有些含蓄+混亂。。。切勿隨意模仿

/* ********************************************** Author      : wuyiqi Created Time: 2013-8-16 8:24:44 File Name   : hdu 4680.cpp  *********************************************** */  #pragma comment(linker,"/STACK:100000000,100000000")  #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->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);     //插入一個節點前不能忘記清空它的左右兒子          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 *tmp = 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);//此處吐血了一整天,上面的改回來了,這裡卻沒改insert(root,fr);              fr->who = type;          }          tree.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%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",&a);              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%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%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%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%d%d",&u,&l,&r);                  node *tmp = ID[u+2*n];                  int tree = tmp->who;                  printf("%d\n",spt[tree].Solve(l,r));              }          }      }      return 0;  }  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.