HDU1890 Robotic Sort Splay tree反转,删除

news/2023/6/5 22:23:43

  题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890

  题目中涉及数的反转和删除操作,需要用Splay tree来实现。首先对数列排序,得到每个数在数列中的下标x。Splay tree的每个节点标记以它为根的子树是否需要反转,用到懒惰操作,保证nlogn,在每次操作的时候Push_Down()和Push_Up。在建树的时候是数的下标为节点标号建立数,如果要询问数num[i],则把num[i]在数列中的下标旋转到根节点root,size[ch[root][0]]+已经排好序的数的数目就是答案。注意,这里因为涉及到数的反转操作,因此在Splay()操作的时候,应该先Push_Down(),然后再判断旋转操作。。

  1 //STATUS:C++_AC_256MS_2700KB
  2 #include <functional>
  3 #include <algorithm>
  4 #include <iostream>
  5 //#include <ext/rope>
  6 #include <fstream>
  7 #include <sstream>
  8 #include <iomanip>
  9 #include <numeric>
 10 #include <cstring>
 11 #include <cassert>
 12 #include <cstdio>
 13 #include <string>
 14 #include <vector>
 15 #include <bitset>
 16 #include <queue>
 17 #include <stack>
 18 #include <cmath>
 19 #include <ctime>
 20 #include <list>
 21 #include <set>
 22 #include <map>
 23 using namespace std;
 24 //using namespace __gnu_cxx;
 25 //define
 26 #define pii pair<int,int>
 27 #define mem(a,b) memset(a,b,sizeof(a))
 28 #define lson l,mid,rt<<1
 29 #define rson mid+1,r,rt<<1|1
 30 #define PI acos(-1.0)
 31 //typedef
 32 typedef __int64 LL;
 33 typedef unsigned __int64 ULL;
 34 //const
 35 const int N=100010;
 36 const int INF=0x3f3f3f3f;
 37 const int MOD=100000,STA=8000010;
 38 const LL LNF=1LL<<60;
 39 const double EPS=1e-8;
 40 const double OO=1e15;
 41 const int dx[4]={-1,0,1,0};
 42 const int dy[4]={0,1,0,-1};
 43 const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
 44 //Daily Use ...
 45 inline int sign(double x){return (x>EPS)-(x<-EPS);}
 46 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
 47 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
 48 template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
 49 template<class T> inline T Min(T a,T b){return a<b?a:b;}
 50 template<class T> inline T Max(T a,T b){return a>b?a:b;}
 51 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
 52 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
 53 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
 54 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
 55 //End
 56 
 57 #define Key_value ch[ch[root][1]][0]
 58 int pre[N],ch[N][2];  //分别表示父结点,键值,左右孩子(0为左孩子,1为右孩子),根结点,结点数量
 59 int sz[N],st[N];   //子树规模,内存池
 60 int root,tot,top;   //根节点,根节点数量,内存池容量
 61 //题目特定数据
 62 struct Node{
 63     int num,idx;
 64 }nod[N];
 65 bool rev[N];
 66 int n;
 67 //debug部分copy from hh
 68 void Treaval(int x) {
 69     if(x) {
 70         Treaval(ch[x][0]);
 71         printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d rev = %2d\n",x,ch[x][0],ch[x][1],pre[x],sz[x],rev[x]);
 72         Treaval(ch[x][1]);
 73     }
 74 }
 75 void debug() {printf("%d\n",root);Treaval(root);}
 76 //以上Debug
 77 //新建一个结点
 78 void NewNode(int &x,int fa,int k)
 79 {
 80  //   if(top)x=st[--top];
 81  //   else x=++tot;
 82     x=k;
 83     pre[x]=fa;
 84     sz[x]=1;
 85     rev[x]=0;
 86     ch[x][0]=ch[x][1]=0;  //左右孩子为空
 87 }
 88 
 89 void Push_Up(int x)
 90 {
 91     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
 92 }
 93 
 94 void Push_Down(int x)
 95 {
 96     if(rev[x]){
 97         rev[ch[x][0]]^=1;
 98         rev[ch[x][1]]^=1;
 99         swap(ch[x][0],ch[x][1]);
100         rev[x]=0;
101     }
102 }
103 //旋转,kind为1为右旋,kind为0为左旋
104 void Rotate(int x,int kind)
105 {
106     int y=pre[x],z=pre[y];
107     Push_Down(y);
108     Push_Down(x);  //先把y的标记向下传递,再把x的标记往下传递
109     //类似SBT,要把其中一个分支先给父节点
110     ch[y][!kind]=ch[x][kind];
111     pre[ch[x][kind]]=y;
112     //如果父节点不是根结点,则要和父节点的父节点连接起来
113     if(z)ch[z][ch[z][1]==y]=x;
114     pre[x]=z;
115     ch[x][kind]=y;
116     pre[y]=x;
117     Push_Up(y);  //维护y结点,不要维护x节点,x节点会再次Push_Down,最后维护一下x节点即可
118 }
119 //Splay调整,将根为r的子树调整为goal
120 void Splay(int x,int goal)
121 {
122     int y,z,kind;
123     while(pre[x]!=goal){
124         //父节点即是目标位置,goal为0表示,父节点就是根结点
125         y=pre[x];
126         Push_Down(pre[y]);Push_Down(y);Push_Down(x);   //设计到反转操作,要先更新,然后在判断!!
127         if(pre[y]==goal){
128             Rotate(x,ch[y][0]==x);
129         }
130         else {
131             kind=ch[pre[y]][0]==y;
132             //两个方向不同,则先左旋再右旋
133             if(ch[y][kind]==x){
134                 Rotate(x,!kind);
135                 Rotate(x,kind);
136             }
137             //两个方向相同,相同方向连续两次
138             else {
139                 Rotate(y,kind);
140                 Rotate(x,kind);
141             }
142         }
143     }
144     //更新根结点
145     Push_Up(x);
146     if(goal==0)root=x;
147 }
148 //建树,中间结点先建立,然后分别对区间两端在左右子树建立
149 void BuildTree(int &x,int l,int r,int fa)
150 {
151     if(l>r)return;
152     int mid=(l+r)>>1;
153     NewNode(x,fa,mid);
154     BuildTree(ch[x][0],l,mid-1,x);
155     BuildTree(ch[x][1],mid+1,r,x);
156     Push_Up(x);
157 }
158 
159 int cmp(Node a,Node b)
160 {
161     return a.num!=b.num?a.num<b.num:a.idx<b.idx;
162 }
163 
164 void Init()
165 {
166     root=tot=top=0;
167     ch[root][0]=ch[root][1]=pre[0]=sz[0]=rev[0]=0;
168 
169     for(int i=1;i<=n;i++){
170         scanf("%d",&nod[i].num);
171         nod[i].idx=i;
172     }
173     sort(nod+1,nod+n+1,cmp);
174     BuildTree(root,1,n,0);
175 }
176 
177 int Get_Max(int x)
178 {
179     Push_Down(x);
180     while(ch[x][1]){
181         x=ch[x][1];
182         Push_Down(x);
183     }
184     return x;
185 }
186 
187 void Remove()
188 {
189     if(ch[root][0]==0){
190         root=ch[root][1];
191         pre[root]=0;
192     }
193     else {
194         int x=Get_Max(ch[root][0]);
195         Splay(x,root);
196         ch[x][1]=ch[root][1];
197         pre[ch[root][1]]=x;
198         root=x;
199         pre[root]=0;
200         Push_Up(root);
201     }
202 }
203 
204 int main()
205 {
206  //   freopen("in.txt","r",stdin);
207     int i,j;
208     while(~scanf("%d",&n) && n)
209     {
210         Init();
211         for(i=1;i<n;i++){
212             Splay(nod[i].idx,0);
213             rev[ch[root][0]]^=1;
214             printf("%d ",i+sz[ch[root][0]]);
215             Remove();
216         }
217         printf("%d\n",n);
218     }
219     return 0;
220 }

 

转载于:https://www.cnblogs.com/zhsl/p/3210206.html


https://dhexx.cn/news/show-18358.html

相关文章

网关Gateway断⾔+过滤器整合注册中心Nacos项目实战

网关Gateway断⾔过滤器整合注册中心Nacos项目实战一、前言二、网关介绍三、基本网关转发1、创建Gateway项目2、配置四、整合注册中心Nacos1、添加Nacos依赖2、启动类开启支持3、修改配置文件4、网关访问的代码五、Gateway内置断言实现接口定时下线与强制参数六、自定义全局过滤…

Hadoop的体系结构

HDFS和MapReduce是Hadoop的两大核心。而整个Hadoop的体系结构主要是通过HDFS来实现对分布式存储的底层支持的&#xff0c;并且它会通过MapReduce来实现对分布式并行任务处理的程序支持。 1、HDFS的体系结构 HDFS采用了主从&#xff08;Master/Slave&#xff09;结构模型&#x…

Redis分布式锁实现

Redis分布式锁实现一、Redis分布式锁的出现二、普通分布式锁&#xff08;不推荐&#xff09;1、pom依赖2、普通版本的分布式锁3、redis分布式锁保证三、升级版分布式锁1、工具类2、场景一程序运行时间大于锁时间提前结束3、场景二程序运行时间小于锁自动释放时间&#xff0c;触…

Unity NGUI 创建简单的按钮

Unity版本&#xff1a;4.5.1  NGUI版本&#xff1a;3.6.5 注意NGUI版本&#xff0c;网上的大部分教程都是2.x版本的&#xff0c;在步骤上面略有不同&#xff0c;此文适合初学者。 示例&#xff1a; 通过NGUI创建一个背景和按钮。 1.首先创建一个新场景&#xff0c;并保存&…

UVa - 11283 - PLAYING BOGGLE

先上题目 Problem F PLAYING BOGGLE Boggle is a classic word game played on a 4 by 4 grid of letters. The letter grid is randomly generated by shaking 16 cubes labeled with a distribution of letters similar to that found in English words. Players try to find…

Open-Feign整合hystrix降级熔断实战

Open-Feign整合hystrix降级熔断实战一、服务端1、配置文件2、控制层二、客户端1、依赖2、配置文件3、启动类4、在控制层当中调用5、创建一个类实现服务FeignClient接口6、在服务FeignClient接口上配置FallBack实现类三、测试1、场景一服务正常调用2、场景二当被调服务停止运行时…

图的全局最小割的Stoer-Wagner算法及例题

Stoer-Wagner算法基本思想&#xff1a;如果能求出图中某两个顶点之间的最小割&#xff0c;更新答案后合并这两个顶点继续求最小割&#xff0c;到最后就得到答案。 算法步骤&#xff1a; ------------------------------------------------------------------------------------…

学习消息中间件Kafka从配置到基本应用

学习消息中间件Kafka从配置到基本应用一、服务器安装配置Kafka1、配置介绍与修改2、启动3、配置开机自启4、如果不使用自带的zookeeper二、Kafka的使用场景1、异步处理2、应用解耦3、流量削锋4、日志处理5、消息通讯三、点对点消息传递模式1、介绍四、发布-订阅消息传递模式1、…

【译】ASP.NET MVC 5 教程 - 1:入门

本教程将教你使用Visual Studio 2013 预览版构建 ASP.NET MVC 5 Web 应用程序 的基础知识。本主题还附带了一个采用 C# 源代码的 Visual Web Developer 项目。下载C# 版本。 入门 Visual Studio 是一个集成的开发环境。就像您使用 Microsoft Word 写文档&#xff0c;您将使用 I…

Redis雪崩、穿透、击穿补充学习与布隆过滤器

Redis学习补充与布隆过滤器一、缓存雪崩1、介绍2、处理雪崩数据二、缓存穿透1、介绍2、处理穿透数据三、缓存击穿2、处理击穿数据四、Redis其他知识1、Redis为何这么快2、Redis的持久化策略五、布隆过滤器1、安装2、介绍布隆过滤器3、使用布隆过滤器BloomFilter解决Redis的缓存…