zoukankan      html  css  js  c++  java
  • hdu2475Box(splay树形转线性)

    链接

    推荐一篇帖子

    http://blog.csdn.net/lyhypacm/article/details/6734748

    这题暴力不可行主要是因为这颗树可能极度不平衡,不能用并查集是不能路径压缩,这样时间复杂度是很高的。

    可以用伸展树主要是因为它的伸展性,每次操作后可以通过伸展使这棵树更好的保持平衡。

    这题还是值得记录一下的,从早上做到了晚上,

    第一次错误,定义了全局的n以及局部的n使得取得结果不正确,以后还是统一习惯,要么写在全局要么写在局部。

    第二次错误,vector初始化没有初始到0导致后面的数据跑不动,以后初始化的操作都从0开始。

    第三次错误,debug了n久,建树的时候误把根节点的父亲节点写成了根,应该是0,自以为不会出错的地方也要认真检查。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 #include<stack>
     11 using namespace std;
     12 #define N 100010
     13 #define LL long long
     14 #define INF 0xfffffff
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 int n,po[N];
     19 vector<int>ed[N];
     20 vector<int>dd;
     21 
     22 struct splay_tree
     23 {
     24     int pre[N];
     25     int ch[N][2];
     26     int root,tot,num;
     27     int key[N];
     28 //    void dfs(int x)
     29 //    {
     30 //        if(x)
     31 //        {
     32 //            dfs(ch[x][0]);
     33 //            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d,key=%2d
    ",
     34 //                   x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
     35 //            dfs(ch[x][1]);
     36 //        }
     37 //    }
     38 //    void debug()
     39 //    {
     40 //        printf("root:%d
    ",root);
     41 //        dfs(root);
     42 //    }
     43 //以上用于debug*/
     44     void newnode(int &x,int v,int fa)//新建一结点
     45     {
     46         x = ++tot;
     47         ch[x][0]=ch[x][1] = 0;
     48         pre[x] = fa;
     49         key[x] = v;
     50         po[v] = x;
     51     }
     52     void pushup(int w)//由儿子更新其父亲
     53     {
     54     }
     55     void rotate(int r,int kind)//旋转操作,根据kind进行左旋和右旋
     56     {
     57         int y = pre[r];
     58         ch[y][!kind] = ch[r][kind];
     59         pre[ch[r][kind]] = y;
     60         if(pre[y])
     61         {
     62             ch[pre[y]][ch[pre[y]][1]==y] = r;
     63         }
     64         pre[r] = pre[y];
     65         ch[r][kind] = y;
     66         pre[y] = r;
     67         pushup(y);
     68         pushup(r);
     69     }
     70     void splay(int r,int goal)//将r结点旋至goal下
     71     {
     72         while(pre[r]!=goal)
     73         {
     74             if(pre[pre[r]]==goal)
     75             {
     76                 rotate(r,ch[pre[r]][0]==r);
     77             }
     78             else
     79             {
     80                 int y = pre[r];
     81                 int kind = (ch[pre[y]][0]==y);
     82                 if(ch[y][kind]==r)
     83                 {
     84                     rotate(r,!kind);
     85                     rotate(r,kind);
     86                 }
     87                 else
     88                 {
     89                     rotate(y,kind);
     90                     rotate(r,kind);
     91                 }
     92             }
     93         }
     94         pushup(r);
     95         if(goal==0) root = r;
     96     }
     97     int get_min(int x)
     98     {
     99         while(ch[x][0])
    100             x =  ch[x][0];
    101         return x;
    102     }
    103     int get_max(int x)
    104     {
    105         while(ch[x][1])
    106             x = ch[x][1];
    107         return x;
    108     }
    109     void update(int x,int y) //更新区间信息
    110     {
    111         int l = po[x],r = po[x+n];
    112         splay(l,0);
    113         splay(r,0);
    114         int ll = ch[l][0];
    115         int rr = ch[r][1];
    116         pre[ll] = pre[rr] = 0;
    117         ch[r][1] = ch[l][0] = 0;
    118 
    119         int tll = get_max(ll);
    120         if(tll!=0)
    121             ch[tll][1] = rr;
    122         pre[rr] = tll;
    123 
    124         if(y==0) return ;
    125         if(query(y)==x)
    126         {
    127             ch[r][1] = rr;
    128             ch[l][0] = ll;
    129             pre[ll] = l;
    130             pre[rr] = r;
    131             ch[tll][1] = 0;
    132             pre[0] = 0;
    133             return ;
    134         }
    135 
    136         if(rr!=0) splay(rr,0);
    137         int tt = po[y];
    138         splay(tt,0);
    139         int tq = get_min(ch[tt][1]);
    140         splay(tq,tt);
    141         ch[tq][0] = r;
    142         pre[r] = tq;
    143     }
    144     int query(int x)//询问l,r区间,将第l-1个结点旋自根,第r+1个结点旋自根的有儿子,
    145     {
    146         splay(po[x],0);
    147         int k = get_min(po[x]);
    148         return key[k];
    149     }
    150     void build(int &x,int l,int r,int fa)
    151     {
    152         int m = (l+r)>>1;
    153         if(l>r) return ;
    154         newnode(x,dd[m],fa);
    155         build(ch[x][0],l,m-1,x);
    156         build(ch[x][1],m+1,r,x);
    157         pushup(x);
    158     }
    159     void init()
    160     {
    161         root = tot = 0;
    162         memset(ch,0,sizeof(ch));
    163         memset(pre,0,sizeof(pre));
    164         memset(key,0,sizeof(key));
    165         memset(po,0,sizeof(po));
    166     }
    167 } SP;
    168 void dfs(int u)
    169 {
    170     int i;
    171     dd.push_back(u);
    172     for(i = 0; i  < ed[u].size(); i++)
    173     {
    174         int v = ed[u][i];
    175         dfs(v);
    176     }
    177     dd.push_back(u+n);
    178 }
    179 int main()
    180 {
    181     int i;
    182     int q;
    183     int mark = false;
    184     while(scanf("%d",&n)!=EOF)
    185     {
    186         if(mark)
    187             puts("");
    188         else
    189             mark = true;
    190         SP.init();
    191         for(i = 0; i <= n; i++)
    192         {
    193             ed[i].clear();
    194         }
    195         dd.clear();
    196         for(i = 1; i <= n; i++)
    197         {
    198             int x;
    199             scanf("%d",&x);
    200             ed[x].push_back(i);
    201         }
    202         dfs(0);
    203         int o = 1;
    204         scanf("%d",&q);
    205         stack<int>st;
    206         for(i = 1 ; i < dd.size()-1 ; i++)
    207         {
    208             int x = dd[i];
    209             if(x<=n) st.push(x);
    210             else st.pop();
    211             if(st.empty())
    212             {
    213                 SP.build(SP.root,o,i,0);
    214                 o = i+1;
    215             }
    216         }
    217         int stt = 1;
    218         while(q--)
    219         {
    220             char sq[100];
    221             int x,y;
    222             scanf("%s",sq);
    223             if(sq[0]=='Q')
    224             {
    225                 scanf("%d",&x);
    226                 printf("%d
    ",SP.query(x));
    227             }
    228             else
    229             {
    230                 scanf("%d%d",&x,&y);
    231                 SP.update(x,y);
    232             }
    233         }
    234     }
    235     return 0;
    236 }
    View Code
  • 相关阅读:
    学习使用&运算符
    企业发放的奖金根据利润提成。
    取一个整数a从右端开始的47位。
    jQuery Select操作大集合
    js 获取某年某月的最后一天
    sql 语句区分大小写查询
    js 冒泡排序
    一个初学者的程序自学计划
    JWNL体验
    (转)GIS相关的SCI、EI期刊
  • 原文地址:https://www.cnblogs.com/shangyu/p/3801761.html
Copyright © 2011-2022 走看看