zoukankan      html  css  js  c++  java
  • bzoj2733 永无乡 平衡树按秩合并

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733

    题意:动态连边,求出某个联通块中权值第$k$小的点。

    首先,看到名次果断想平衡树……查询这个问题很好解决,但是合并……恐怕只能暴力修改了吧……

    这时候我们需要一个武器:启发式合并,通俗的讲就是小的插到大的里面去突然污了起来。我们可以想象一下,如果把大的那棵树合并到小的那棵去,那么每个节点暴力合并……时间代价不堪设想……因此按秩合并可以有效减短合并时间……然后就是暴力插点删点就行了……

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define lc(x) ((x)->ch[0])
      6 #define rc(x) ((x)->ch[1])
      7 #define size(x) ((x)?(x->siz):0)
      8 using namespace std;
      9 const int maxn=100005;
     10 int n,m;
     11 struct node
     12 {
     13     int val,fix,siz,id;
     14     node *ch[2];
     15     node(){}
     16     node(int v=0,int d=0):val(v),fix(rand()),id(d),siz(1){memset(ch,0,sizeof(ch));}
     17     void maintain(){siz=1+size(ch[0])+size(ch[1]);}
     18 };
     19 struct Treap
     20 {
     21     node *root[maxn];
     22     void rotate(node* &rt,int d)
     23     {
     24         node *t=rt->ch[d^1];rt->ch[d^1]=t->ch[d];t->ch[d]=rt;
     25         rt->maintain();t->maintain();rt=t;
     26     }
     27     void insert(node* &rt,int x,int y)
     28     {
     29         if(!rt){rt=new node(x,y);return;}
     30         int d=rt->val>x;insert(rt->ch[d^1],x,y);rt->maintain();
     31         if(rt->ch[d^1]->fix<rt->fix)rotate(rt,d);
     32         rt->maintain();
     33     }
     34     void del(node* &rt,int x)
     35     {
     36         if(rt->val==x)
     37         {
     38             if(lc(rt)&&rc(rt))
     39             {
     40                 int d=lc(rt)->fix>rc(rt)->fix;
     41                 rotate(rt,d);del(rt->ch[d],x);
     42             }
     43             else
     44             {
     45                 node *t=NULL;
     46                 if(lc(rt))t=lc(rt);else t=rc(rt);
     47                 delete(rt);rt=t;
     48             }
     49         }
     50         else
     51         {
     52             int d=rt->val>x;
     53             del(rt->ch[d^1],x);rt->maintain();
     54             if(rt->ch[d^1]->fix>rt->fix)rotate(rt,d);
     55         }
     56     }
     57     int rank(node *rt,int x)
     58     {
     59         int res=0;
     60         while(rt)
     61             if(x>rt->val)res+=size(lc(rt))+1,rt=rc(rt);
     62             else rt=lc(rt);
     63         return res;
     64     }
     65     int kth(node *rt,int x)
     66     {
     67         while(rt)
     68         {
     69             if(size(lc(rt))+1==x)return rt->id;
     70             if(size(lc(rt))+1>x)rt=lc(rt);
     71             else x-=size(lc(rt))+1,rt=rc(rt);
     72         }
     73         return -1;
     74     }
     75     void mergeto(node* src,node* &to)
     76     {
     77         if(lc(src))mergeto(lc(src),to);
     78         if(rc(src))mergeto(rc(src),to);
     79         insert(to,src->val,src->id);
     80         delete src,src=NULL;
     81     }
     82 }T;
     83 int f[maxn];
     84 int getfa(int x)
     85 {
     86     return f[x]==x?x:f[x]=getfa(f[x]);
     87 }
     88 void unionn(int x,int y)
     89 {
     90     x=getfa(x),y=getfa(y);
     91     if(x!=y)
     92     {
     93         if(T.root[x]->siz<T.root[y]->siz)f[x]=y,T.mergeto(T.root[x],T.root[y]);
     94         else f[y]=x,T.mergeto(T.root[y],T.root[x]);
     95     }
     96 }
     97 int a[maxn];
     98 int haha()
     99 {
    100     scanf("%d%d",&n,&m);
    101     for(int i=1;i<=n;i++)scanf("%d",&a[i]),T.root[i]=new node(a[i],i),f[i]=i;
    102     for(int i=1;i<=m;i++)
    103     {
    104         int x,y;scanf("%d%d",&x,&y);
    105         unionn(x,y);
    106     }
    107     int q;scanf("%d",&q);
    108     for(int i=1;i<=q;i++)
    109     {
    110         char opt[3];int x,y;scanf("%s%d%d",opt,&x,&y);
    111         if(opt[0]=='Q')printf("%d
    ",T.kth(T.root[getfa(x)],y));
    112         else unionn(x,y);
    113     }
    114 }
    115 int sb=haha();
    116 int main(){;}
    bzoj2733
  • 相关阅读:
    关于js计算非等宽字体宽度的方法
    [NodeJs系列]聊一聊BOM
    Vue.js路由管理器 Vue Router
    vue 实践技巧合集
    微任务、宏任务与Event-Loop
    事件循环(EventLoop)的学习总结
    Cookie、Session和LocalStorage
    MySQL 树形结构 根据指定节点 获取其所在全路径节点序列
    MySQL 树形结构 根据指定节点 获取其所有父节点序列
    MySQL 创建函数报错 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7588712.html
Copyright © 2011-2022 走看看