• POJ 2985 名次树


    题意:1~n个猫,有合并操作,有询问操作,合并两只猫所在的集合,询问第K大的集合。

    分析:合并操作用并查集,用size维护,询问操作用Treap。注意优化,不能刚开始就把所有size = 1放到名次树中,是1的不做处理,而是不够的时候返回一个1;

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 
      5 using namespace std;
      6 
      7 struct Node {
      8     Node *ch[2];
      9     int r;
     10     int v;
     11     int s;
     12     Node(int v):v(v) {ch[0]=ch[1] = NULL;r=rand();s=1;}
     13     bool operator < (const Node& rhs) const {
     14         return r < rhs.r;
     15     }
     16 
     17     int cmp(int x) const {
     18         if(x==v) return -1;
     19         return x < v ? 0 : 1;
     20     }
     21 
     22     void maintain() {
     23         s = 1;
     24         if(ch[0]!=NULL) s+=ch[0]->s;
     25         if(ch[1]!=NULL) s+=ch[1]->s;
     26     }
     27 
     28 }*root;
     29 
     30 void rotate(Node* &o,int d)
     31 {
     32     Node *k=o->ch[d^1];
     33     o->ch[d^1]=k->ch[d];
     34     k->ch[d]=o;
     35     o->maintain();
     36     k->maintain();
     37     o=k;
     38 }
     39 void insert(Node* &o,int v)//可插入重复值
     40 {
     41     if(o==NULL) o=new Node(v);
     42     else
     43     {
     44         int d=v < o->v? 0:1;
     45         insert(o->ch[d],v);
     46         if(o->ch[d]->r > o->r)
     47             rotate(o,d^1);
     48     }
     49     o->maintain();
     50 }
     51 void remove(Node* &o,int v)
     52 {
     53     int d=o->cmp(v);
     54     if(d==-1)
     55     {
     56         Node *u=o;
     57         if(o->ch[0] && o->ch[1])
     58         {
     59             int d2= o->ch[0]->r < o->ch[1]->r ?0:1;
     60             rotate(o,d2);
     61             remove(o->ch[d2],v);
     62         }
     63         else
     64         {
     65             if(o->ch[0]==NULL) o=o->ch[1];
     66             else o=o->ch[0];
     67             delete u;
     68         }
     69     }
     70     else remove(o->ch[d],v);
     71     if(o) o->maintain();
     72 }
     73 
     74 
     75 int kth(Node *o,int k)//返回第k大的值,不是第k小
     76 {
     77     if(o==NULL || k<=0 || k> o->s) return 1;
     78     int s = (o->ch[1]==NULL)?0:o->ch[1]->s;
     79     if(k==s+1) return o->v;
     80     else if(k<=s) return kth(o->ch[1],k);
     81     else return kth(o->ch[0],k-s-1);
     82 }
     83 
     84 const int maxn=200000+1000;
     85 int n,m;
     86 int father[maxn],size[maxn];
     87 
     88 
     89 int Find_Set(int x) {
     90     if(father[x]!=x)
     91         father[x] = Find_Set(father[x]);
     92     return father[x];
     93 }
     94 
     95 int main()
     96 {
     97     //freopen("in.txt","r",stdin);
     98     root = NULL;
     99     for(int i=0;i<maxn;i++) {
    100         father[i] = i;
    101         size[i] = 1;
    102     }
    103     scanf("%d%d",&n,&m);
    104     //for(int i=0;i<n;i++)
    105         //insert(root,1);
    106     while(m--) {
    107         int cmp;
    108         scanf("%d",&cmp);
    109         if(cmp==0) {
    110             int u,v;
    111             scanf("%d%d",&u,&v);
    112             int fx = Find_Set(u);
    113             int fy = Find_Set(v);
    114             if(fx!=fy)
    115             {
    116                 if(size[fx]!=1) remove(root,size[fx]);
    117                 if(size[fy]!=1) remove(root,size[fy]);
    118                 father[fy] = fx;
    119                 size[fx]+=size[fy];
    120                 insert(root,size[fx]);
    121             }
    122         }
    123         else {
    124             int k;
    125             scanf("%d",&k);
    126             printf("%d
    ",kth(root,k));
    127         }
    128     }
    129 
    130 
    131     return 0;
    132 }
    View Code
  • 相关阅读:
    C语言|博客作业02
    少走弯路的十条忠告
    怎么算是优秀的程序员写给工作2,3年了的同行
    .NET世界的M型化原文作者奚江华
    工作以后十不要 减少奋斗30年
    <转>[创业经验]程序员创业:我的软件推广成功之路
    一个程序员的C#命名规则<转>
    推荐奚江华著《圣殿祭祀ASP.NET 3.5 专家技术手册 C#篇及他的TW博客进入方法》
    C#算法
    使用 DataFormatString 属性来提供列中各项的自定义格式
  • 原文地址:https://www.cnblogs.com/TreeDream/p/7209545.html
Copyright © 2020-2023  润新知