hdu 1890 splay区间翻转
来源:互联网 发布:公务员面试技巧知乎 编辑:程序博客网 时间:2024/04/29 13:47
链接 : http://acm.hdu.edu.cn/showproblem.php?pid=1890
下传翻转标记的时候要特别注意
每次将第i个数到第i大的数之间的数翻转,然后删除第i大的数
/*区间翻转,注意标记的下传*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define L ch[x][0]#define R ch[x][1]#define KT (ch[ ch[rt][1] ][0])const int maxn = 100010;int cmp(pair<int,int> a,pair<int,int> b){if(a.first!=b.first) return a.first<b.first;return a.second < b.second;}struct SplayTree {int sz[maxn];int ch[maxn][2];int pre[maxn];int rt,top;inline void down(int x){ if(flip[x]) {flip[ L ] ^= 1;flip[ R ] ^= 1;swap(L,R);flip[x]=0;}}inline void up(int x){sz[x]=1+sz[ L ] + sz[ R ];}inline void Rotate(int x,int f){int y=pre[x];down(y);down(x);ch[y][!f] = ch[x][f];pre[ ch[x][f] ] = y;pre[x] = pre[y];if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;ch[x][f] = y;pre[y] = x;up(y);}inline void Splay(int x,int goal){//将x旋转到goal的下面down(x);//防止pre[x]就是目标点,下面的循环就进不去了,x的信息就传不下去了while(pre[x] != goal){down(pre[pre[x]]); down(pre[x]);down(x);//在旋转之前需要先下传标记,因为节点的位置可能会发生改变if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);else {int y=pre[x],z=pre[y];int f = (ch[z][0]==y);if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);else Rotate(y,f),Rotate(x,f);}}up(x);if(goal==0) rt=x;}inline void RTO(int k,int goal){//将第k位数旋转到goal的下面int x=rt;down(x);while(sz[ L ]+1 != k) {if(k < sz[ L ] + 1 ) x=L;else {k-=(sz[ L ]+1);x = R;}down(x);}Splay(x,goal);}void vist(int x){if(x){printf("结点%2d : 左儿子 %2d 右儿子 %2d %2d flip:%d\n",x,L,R,val[x],flip[x]);vist(L);vist(R);}}void Newnode(int &x,int c,int f){x=++top;flip[x]=0;L = R = 0; pre[x] = f;sz[x]=1; val[x]=c;}inline void build(int &x,int l,int r,int f){if(l>r) return ;int m=l+r>>1;Newnode(x,num[id[m]].first,f);mp[id[m]]=x;build(L , l , m-1 , x);build(R , m+1 , r , x);pre[x]=f;up(x);}inline void init(int n){ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;rt=top=0; flip[0]=0; val[0]=0;for(int i=1;i<=n;i++) {scanf("%d",&num[i].first);num[i].second=i;}sort(num+1,num+n+1,cmp);for(int i=1;i<=n;i++) id[num[i].second] = i;build(rt,1,n,0);}void Del(){ int t=rt; if(ch[rt][1]) { rt=ch[rt][1]; RTO(1,0); ch[rt][0]=ch[t][0]; if(ch[rt][0]) pre[ch[rt][0]]=rt; } else rt=ch[rt][0]; pre[rt]=0; up(rt);}void solve(int n){for(int i=1;i<=n;i++) {Splay(mp[i],0);printf("%d",i+sz[ ch[rt][0] ]);flip[ch[rt][0]]^=1;Del(); printf(i==n ? "\n": " ");} }pair<int,int> num[maxn];int id[maxn];int mp[maxn];int flip[maxn];int val[maxn];}spt;int main(){int n;while(scanf("%d",&n),n){spt.init(n);spt.solve(n);}return 0;}
- hdu 1890 splay区间翻转
- HDU 1890 splay区间翻转
- HDU 1890 Splay区间翻转
- hdu 1890 splay 区间翻转
- hdu 1890 Splay区间最小值、区间翻转
- 【HDU】1890 Robotic Sort 翻转区间【splay】
- HDU 1890 Robotic Sort(Splay 区间翻转)
- hdu 1890伸展树(splay tree)区间翻转
- hdu-1890-Robotic Sort-splay tree-区间翻转
- HDU 1890 Robotic Sort 单点查找区间翻转 Splay裸题
- hdu 1890 Robotic Sort (Splay区间翻转)
- HDU 1890 Robotic Sort [平衡树splay 区间翻转]
- hdu 3487 区间 翻转 切割 插入 splay
- HDU 3487 splay区间翻转切割
- Splay区间翻转
- 区间翻转问题 Splay
- Splay树(区间翻转)—— HDU 1890 Robotic Sort
- hdu 3487 Play with Chain splay 区间翻转,插入,删除
- 解决PHP之 Allowed memory size of xxx bytes exhausted
- android 系统定制的小技巧(网络收集)
- Android.mk介绍
- POJ 3420 Quad Tiling
- [HDU-2660] DFS
- hdu 1890 splay区间翻转
- POJ 2135 最小费用流模板题
- js新手弱弱错误大全
- bzoj 1503 [NOI2004]郁闷的出纳员 splay
- [Ubuntu]: Ubuntu 10.04 LTS iptables NAT and DHCP server
- ARM零碎知识点总结
- 一个Linux下C线程池的实现
- 整数拆分的两种解法(已完成)
- 结合属性文件的工厂模式(java反射的应用)