HDU 3487 Play with Chain | Splay

Play with Chain

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

【Problem Description】
YaoYao is fond of playing his chains. He has a chain containing n diamonds on it. Diamonds are numbered from 1 to n. At first, the diamonds on the chain is a sequence: 1, 2, 3, …, n. He will perform two types of operations:
CUT a b c: He will first cut down the chain from the ath diamond to the bth diamond. And then insert it after the cth diamond on the remaining chain. For example, if n=8, the chain is: 1 2 3 4 5 6 7 8; We perform “CUT 3 5 4”, Then we first cut down 3 4 5, and the remaining chain would be: 1 2 6 7 8. Then we insert “3 4 5” into the chain before 5th diamond, the chain turns out to be: 1 2 6 7 3 4 5 8.
FLIP a b: We first cut down the chain from the ath diamond to the bth diamond. Then reverse the chain and put them back to the original position. For example, if we perform “FLIP 2 6” on the chain: 1 2 6 7 3 4 5 8. The chain will turn out to be: 1 4 3 7 6 2 5 8
He wants to know what the chain looks like after perform m operations. Could you help him?
【Input】
There will be multiple test cases in a test data. For each test case, the first line contains two numbers: n and m (1≤n, m≤3*100000), indicating the total number of diamonds on the chain and the number of operations respectively. Then m lines follow, each line contains one operation. The command is like this: CUT a b c   // Means a CUT operation, 1 ≤ a ≤ b ≤ n, 0≤ c ≤ n-(b-a+1). FLIP a b    // Means a FLIP operation, 1 ≤ a < b ≤ n. The input ends up with two negative numbers, which should not be processed as a case.
【Output】
For each test case, you should print a line with n numbers. The ith number is the number of the ith diamond on the chain.
【Sample Input】
8 2 
CUT 3 5 4 
FLIP 2 6 
-1 -1

【Sample Output】

1 4 3 7 6 2 5 8

 

【题意】

给出一列数,然后对整个数列执行两种操作:切下一段插入到另外的位置,或者把其中的一整段整个翻转一下。

求经过一系列操作之后,数列最后的样子。

 

【分析】

数据范围最高能够到达3e5那么大,因此算法至少要是O(nlogn)复杂度以下才可能达到要求。

考虑采用Splay解决(这样的题目只能用这种动态维护的树结构不是么?)

 

初始先建树,把1~n加入Splay树。由于数列在后面是要被打乱顺序的,Splay二叉平衡树的性质只有在初始的时候是被保持的,之后是靠size,即每个点在中序遍历中的位置来维护。最后输出数列则只需要中序遍历一遍即可。

切割操作:若要切下a~b段,则把第a-1个结点移到根,把第b+1个结点移到根以下(即跟的右子树),则整个a~b段就落在b+1的左子树上,切出来。插入到c的时候,将c移到根,c+1移到根的右子树,则切出来的插入到c+1的左子树即可

翻转操作:用上面相同的方法把a~b整合到一棵子树上,然后可以参考线段树标记的方法,通过标记来完成访问结点的翻转等操作。

具体可以在纸上模拟一下......

 

【教训】

教训还是比较惨痛的...卡在这道题上好久了。

首先是输入输出以后要特别注意结尾方式,两个负数结尾还是两个-1结尾

把各种可能出现的不同情况考虑完整

 

  1 /* ***********************************************
  2 MYID    : Chen Fan
  3 LANG    : G++
  4 PROG    : HDU3487
  5 ************************************************ */
  6 
  7 #include <iostream>
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <algorithm>
 11 
 12 using namespace std;
 13 
 14 #define MAXN 300010
 15 
 16 int sons[MAXN][2];
 17 int father[MAXN],size[MAXN],data[MAXN],list[MAXN];
 18 bool flag[MAXN];
 19 int spt=0,spttail=0;
 20 
 21 void down(int x)
 22 {
 23     if (flag[x])
 24     {
 25         flag[x]=0;
 26         swap(sons[x][0],sons[x][1]);
 27         flag[sons[x][0]]^=1;
 28         flag[sons[x][1]]^=1;
 29     }
 30 }
 31 
 32 void rotate(int x,int w) //rotate(node,0/1)
 33 {
 34     int y=father[x];
 35     down(y);down(x);
 36     sons[y][!w]=sons[x][w];
 37     if (sons[x][w]) father[sons[x][w]]=y;
 38 
 39     father[x]=father[y];
 40     if (father[y]) sons[father[y]][y==sons[father[y]][1]]=x;
 41 
 42     sons[x][w]=y;
 43     father[y]=x;
 44 
 45     size[x]=size[y];
 46     size[y]=size[sons[y][0]]+size[sons[y][1]]+1;
 47 }
 48 
 49 void splay(int x,int y) //splay(node,position)
 50 {
 51     down(x);
 52     while(father[x]!=y)
 53     {
 54         if (father[father[x]]==y) rotate(x,x==sons[father[x]][0]);
 55         else 
 56         {
 57             int t=father[x];
 58             int w=(sons[father[t]][0]==t);
 59             if (sons[t][w]==x)
 60             {
 61                 rotate(x,!w);
 62                 rotate(x,w);
 63             } else 
 64             {
 65                 rotate(t,w);
 66                 rotate(x,w);
 67             }
 68         }
 69     }
 70     if (!y) spt=x;
 71 }
 72 
 73 void select(int x,int v,int p) //select(root,k,position)
 74 {
 75     down(x);
 76     while(v!=size[sons[x][0]]+1)
 77     {
 78         if (v<=size[sons[x][0]]) 
 79         {
 80             x=sons[x][0];
 81             down(x);
 82         }
 83         else 
 84         {
 85             v-=size[sons[x][0]]+1;
 86             x=sons[x][1];
 87             down(x);
 88         }
 89     }
 90     splay(x,p);
 91 }
 92 
 93 bool done=false;
 94 
 95 void outp(int x)
 96 {
 97     down(x);
 98     if (sons[x][0]) outp(sons[x][0]);
 99     if (done) printf(" ");
100     done=true;
101     printf("%d",data[x]);
102     if (sons[x][1]) outp(sons[x][1]);
103 }
104 
105 void maketree(int l,int r)
106 {
107     spttail++;
108     int now=spttail,w=(l+r)/2,ls=0,rs=0;
109     data[now]=w;
110     flag[now]=false;
111     sons[now][0]=0;
112     sons[now][1]=0;
113     
114     if (l<=w-1)
115     {
116         ls=spttail+1;
117         sons[now][0]=ls;
118         father[ls]=now;
119         maketree(l,w-1);
120     }
121     if (w+1<=r)
122     {
123         rs=spttail+1;
124         sons[now][1]=rs;
125         father[rs]=now;
126         maketree(w+1,r);
127     }
128 
129     size[now]=size[ls]+size[rs]+1;
130 }
131 
132 int main()
133 {
134     freopen("3487.txt","r",stdin);
135     
136     int n,m;
137     scanf("%d%d",&n,&m);
138     while(!(n<0&&m<0))
139     {
140         spt=1;
141         spttail=0;
142         father[1]=0;
143         maketree(1,n);
144 
145         for (int i=1;i<=m;i++)
146         {
147             char s[10];
148             scanf("%s",&s);
149             if (s[0]=='C')
150             {
151                 int a,b,c,temp;
152                 scanf("%d%d%d",&a,&b,&c);
153 
154                 if (a>1)
155                 {
156                     select(spt,a-1,0);
157                     if (b<n)
158                     {
159                         select(spt,b+1,spt);
160                         temp=sons[sons[spt][1]][0];
161                         sons[sons[spt][1]][0]=0;
162                         size[spt]-=size[temp];
163                         size[sons[spt][1]]-=size[temp];
164                     } else 
165                     {
166                         temp=sons[spt][1];
167                         sons[spt][1]=0;
168                         size[spt]-=size[temp];
169                     }
170                 } else 
171                 {
172                     if (b<n)
173                     {
174                         select(spt,b+1,0);
175                         temp=sons[spt][0];
176                         sons[spt][0]=0;
177                         size[spt]-=size[temp];
178                     } else temp=spt;
179                 }
180 
181                 if (c>0)
182                 {
183                     select(spt,c,0);
184                     if (c==size[spt])
185                     {
186                         sons[spt][1]=temp;
187                         father[temp]=spt;
188                         size[spt]+=size[temp];
189                     } else
190                     {
191                         select(spt,c+1,spt);
192                         sons[sons[spt][1]][0]=temp;
193                         father[temp]=sons[spt][1];
194                         size[spt]+=size[temp];
195                         size[sons[spt][1]]+=size[temp];
196                     }
197                 } else 
198                 {
199                     if (spt!=temp)
200                     {
201                         select(spt,1,0);
202                         sons[spt][0]=temp;
203                         father[temp]=spt;
204                         size[spt]+=size[temp];
205                     }
206                 }  
207             } else 
208             {
209                 int a,b,temp;
210                 scanf("%d%d",&a,&b);
211                 if (a>1)
212                 {
213                     select(spt,a-1,0);
214                     if (b<n)
215                     {
216                         select(spt,b+1,spt);
217                         temp=sons[sons[spt][1]][0];
218                     } else 
219                     {
220                         temp=sons[spt][1];
221                     }
222                 } else 
223                 {
224                     if (b<n)
225                     {
226                         select(spt,b+1,0);
227                         temp=sons[spt][0];
228                     } else temp=spt;
229                 }
230                 flag[temp]^=1;
231             }
232         }
233         done=false;
234         outp(spt);
235         printf("\n");
236         scanf("%d%d",&n,&m);
237     }
238 
239     return 0;
240 }
View Code

 

 

 

转载于:https://www.cnblogs.com/jcf94/p/4374315.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WIN32程序结构

windows程序基于消息驱动系统&#xff0c;用户的所有行为和事件都被windows转成消息。windows内部对消息的处理:消息生命周期:1.消息产生:windows监控所有具体输入事件硬件设备。当系统收到设备输入事件时。windows将对应事件转成消息。2.消息投递:每个消息都有一个目标窗体接收…

zsh

2019独角兽企业重金招聘Python工程师标准>>> 1. MAC安装zsh后,部分bash 指令失效conda, list, pip, list失效&#xff0c;怎么解决&#xff1f; step1&#xff1a;vim ~/.bash_profile 记录Anaconda的路径地址: export PATH"/Users/XXX/anaconda/bin:$PAT…

导出jar插件_Fluttify输出的Flutter插件工程详解

系列文章&#xff1a;yohom&#xff1a;Fluttify输出的Flutter插件工程详解​zhuanlan.zhihu.comyohom&#xff1a;开发Flutter插件必备原生SDK->Dart接口生成引擎Fluttify介绍​zhuanlan.zhihu.comyohom&#xff1a;如何使用Fluttify开发一个新的Flutter插件​zhuanlan.zhi…

[免费下载应用]iNeuKernel.Ocr 图像数据识别与采集原理和产品化应用

目 录1..... 应用概述... 22..... 免费下载试用... 23..... 视频介绍... 24..... iNeuLink.Ocr图像数据采集应用... 25..... 数据上传到iNeuOS工业互联网操作系统... 46..... Ocr基本概念... 71. 应用概述在工业、军工或航天等领域&#xff0c;有些设备及软件系统比较陈…

hdu 1848(Fibonacci again and again)(SG博弈)

Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8380 Accepted Submission(s): 3462 Problem Description任何一个大学生对菲波那契数列(Fibonacci numbers)应该都不会陌生&#xff…

linux c之gcc编译出现error:lvalue required as unary ‘‘ operand解决办法

1、问题 今天搞epoll实现io复用的时候gcc编译出现这个错误lvalue required as unary & operand&#xff0c;如下图 2、解决办法 accept函数参数如下 int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen); 在第三个参数为了少些代码我是这样写成这样&size…

生成arff文件,csv转为arff

一、什么是arff格式文件 1、arff是Attribute-Relation File Format缩写&#xff0c;从英文字面也能大概看出什么意思。它是weka数据挖掘开源程序使用的一种文件模式。由于weka是个很出色的数据挖掘开源项目&#xff0c;所以使用的比较广&#xff0c;这也无形中推广了它的数据存…

C#中的类

前言今天咱们简单复习下C#中类的相关知识。在刚开始学习编程的时候&#xff0c;都是从面向过程的C语言开始的&#xff0c;它有个特征就是有其执行顺序&#xff0c;先干这&#xff0c;再干那&#xff0c;很直接&#xff0c;也很好理解。但现在学习C#或者JAVA等面向对象的语言&am…

Stopwatch类学习

1、概述:给一条大MSDN的链接关于Stopwatch类最详细的教程 ,然后看着教程自己手动敲一边,加深映象,好记性不如烂键盘,哈哈,开个玩笑&#xff01; 2、类位置:这个类在哪里,这个是重点,虽然C#IDE很强大,但是我们还是得简单的了解下。通过一段代码来说明: using System; namespace …

看看这套WPF开源基础控件库:WPFDevelopers

此项目包含了 微信公众号 《 WPF开发者》 日常开发分享&#xff0c;欢迎Star。运行环境 Visual Studio 2019&#xff0c;dotNet Framework 4.0 SDK欢迎关注微信公众号支持贡献者DrawPrize&#xff08;WPF 实现大转盘抽奖&#xff09;GIF帧数太多&#xff0c;无法上传&#xff0…

如何将EDM营销与多渠道推广方式相结合

目前&#xff0c;消费者每天都会从各种渠道收到信息&#xff0c;如果仅用单一渠道的营销会影响整体营销。多渠道推广方式是所有渠道都要兼顾到从而接触用户&#xff0c;让他接收到他想接收的信息&#xff0c;多渠道的过程中邮件还是非常好的营销方式。你要想让你的EDM营销获得成…

Cannot resolve the collation conflict between SQL_Latin1_General_CP1_CI_AS and Latin1_General_100...

ErrorMessage Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_100_CI_AS" in the equal to operation. 查看SQL Server的Collation SELECT SERVERPROPERTY (Collation) Solution 1. 在安装SQL Server…

语言 ota_荣威RX5 PLUS使用最新的家族设计语言,给人更年轻时尚的感觉

如果要用一个词来形容 荣威RX5 PLUS&#xff0c;我第一个能想到的便是“诚意”。斑马最新VENUS系统、米其林PS4轮胎、双层隔音玻璃、终身原厂质保、终身免费基础保养……从产品到政策&#xff0c;荣威RX5 PLUS的方方面面都显示出了上汽荣威的诚意。从上市到现在&#xff0c;荣威…

C# 制作指示灯(经典)

群友提问&#xff1a;C#中的指示灯怎么做&#xff0c;改变状态有什么好的方法吗&#xff1f;制作指示灯的方法有很多中&#xff1a;比如&#xff1a;通过GDI绘制自定义LED指示灯控件&#xff1b;调用现成的第三方控件库&#xff1b;采用label标签&#xff0c;通过改变背景色实现…

结合ChatGPT和MINDSHOW自动生成PPT

总结/朱季谦 一、首先&#xff0c;通过chatGPT说明你的需求&#xff0c;学会提问是Ai时代最关键的一步。你需要提供一些关键信息&#xff0c;如果没有关键信息&#xff0c;就按照大纲方式让它设计&#xff0c;例如&#xff0c;我让它帮我写一份《2023年年中述职报告》的模版—…

华为怎么删除自带的音乐_原来华为手机相册隐藏剪辑功能!按下这个开关,还能制作音乐相册...

华为手机相册你肯定在用&#xff0c;但除了最近删除、智能搜索之外&#xff0c;你还知道手机相册的其他功能吗&#xff1f;这里就分享一个&#xff0c;相册中隐藏的实用剪辑功能&#xff0c;按下这个开关&#xff0c;还能把照片制作成音乐相册。创作开关首先将华为手机上的相册…

使用 Dapr 缩短软件开发周期,提高生产效率

Microsoft DevOps 文档里的文章&#xff08;https://docs.microsoft.com/zh-cn/azure/devops/report/dashboards/cycle-time-and-lead-time?viewazure-devops&#xff09;中的这张图片在给我们介绍了 什么是周期时间 以及它如何影响我的项目流时非常有影响力。第一次输入 &quo…

各种加密算法

2019独角兽企业重金招聘Python工程师标准>>> 如基本的单向加密算法&#xff1a; BASE64 严格地说&#xff0c;属于编码格式&#xff0c;而非加密算法MD5(Message Digest algorithm 5&#xff0c;信息摘要算法)SHA(Secure Hash Algorithm&#xff0c;安全散列算法)H…

利用Xshell实现非对称秘钥对安全登陆linux服务器(Centos、Ubuntu)

非对称加密算法简述&#xff1a;对称加密算法在加密和解密时使用的是同一个秘钥&#xff1b;而非对称加密算法需要两个密钥来进行加密和解密&#xff0c;这两个秘钥是公开密钥&#xff08;public key&#xff0c;简称公钥&#xff09;和私有密钥&#xff08;private key&#x…

一秒点击屏幕次数测试_安卓App性能专项测试流畅度深度解析

指标背景流畅度&#xff0c;顾名思义是用户感知使用App页面时的流畅情况。“App卡不卡”&#xff0c;这是用户最直接的感受。 但是要用量化之后的数据衡量流畅度&#xff0c;在Android平台这边并没有直接有效的方式/手段去监控。帧率&刷新频率首先需要了解到两个概念&#…