首页 > 代码库 > hdu2475Box(splay树形转线性)
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\n", 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\n",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 else189 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\n",SP.query(x));227 }228 else229 {230 scanf("%d%d",&x,&y);231 SP.update(x,y);232 }233 }234 }235 return 0;236 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。