http://codevs.cn/problem/1743/ (题目链接)

题意

  给出一个序列{a1,a2,a3···},要求维护这样一种操作:将前a1个数反转,若第a1等于1,则停止操作。

Solution

  像这种带有反转区间的操作,大概就是splay了。码了一个晚上。。。

  splay一般就是处理区间反转,区间插入,区间删除这三种线段树等数据结构无法处理的操作,splay难写又难调,经常犯一些鬼畜错误,能不写就尽量不写的好。。splay不是二叉搜索树,但它有一个很优秀的性质:树的中序遍历出来的序列就是原始序列。这样我们方便的就可以处理区间上的问题,比如说对于区间[l,r],我们将l-1splay到树根,将r+1splay到树根的右儿子,那么我们要修改的区间就是树根的右儿子的左儿子子树。

  所以对于这道题,我们每次反转时,先将splay两遍,然后再给节点[l,r]打上标记即可。代码模着hzwer写的,感觉很优秀。

代码

  1. // codevs1743
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<cstdio>
  7. #include<cmath>
  8. #define LL long long
  9. #define inf 2147483640
  10. #define Pi acos(-1.0)
  11. #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
  12. using namespace std;
  13.  
  14. const int maxn=300010;
  15. int a[maxn],tr[maxn][2],fa[maxn],size[maxn],val[maxn],rev[maxn];
  16. int n,ans,rt;
  17.  
  18. void rotate(int x,int &k) {
  19. int y=fa[x],z=fa[y],l,r;
  20. if (x==tr[y][0]) l=0;else l=1;
  21. r=l^1;
  22. if (y==k) k=x;
  23. else tr[z][tr[z][1]==y]=x;
  24. fa[y]=x;fa[x]=z;fa[tr[x][r]]=y;
  25. tr[y][l]=tr[x][r];tr[x][r]=y;
  26. //注意这里一定先更新y的size,再更新x的size.
  27. size[y]=size[tr[y][0]]+size[tr[y][1]]+1;
  28. size[x]=size[tr[x][0]]+size[tr[x][1]]+1;
  29. }
  30. void splay(int x,int &k) {
  31. while (x!=k) {
  32. int y=fa[x],z=fa[y];
  33. if (y!=k) { //如果x,y,z在一条链(形象)上,那么先旋y,再旋x.听说可以使平衡树更加平衡
  34. if (tr[z][0]==y ^ tr[y][0]==z) rotate(x,k); //不在一条链上
  35. else rotate(y,k); //在一条链上
  36. }
  37. rotate(x,k);
  38. }
  39. }
  40. void pushdown(int k) {
  41. int l=tr[k][0],r=tr[k][1];
  42. rev[k]^=1;rev[l]^=1;rev[r]^=1; //如果同一个区间被反转2次,那么就等价于不反转.
  43. swap(tr[k][0],tr[k][1]);
  44. }
  45. int find(int k,int x) { //在树中寻找序列中第rk个数
  46. if (rev[k]) pushdown(k);
  47. int l=tr[k][0],r=tr[k][1];
  48. if (size[l]+1==x) return k;
  49. else if (x<=size[l]) return find(l,x);
  50. else return find(r,x-size[l]-1);
  51. }
  52. void build(int l,int r,int f) {
  53. if (l>r) return;
  54. int mid=(l+r)>>1;
  55. //tr[][]记录当前节点的左儿子与右儿子
  56. if (mid<f) tr[f][0]=mid;
  57. else tr[f][1]=mid;
  58. //size[]记录子树大小,val[]记录数值,fa[]记录父亲.
  59. rev[mid]=0;val[mid]=a[mid];size[mid]=1;fa[mid]=f;
  60. if (l==r) return;
  61. build(l,mid-1,mid);
  62. build(mid+1,r,mid);
  63. size[mid]=size[tr[mid][0]]+size[tr[mid][1]]+1;
  64. }
  65. void rever(int l,int r) {
  66. int x=find(rt,l),y=find(rt,r+2);
  67. splay(x,rt);splay(y,tr[rt][1]);
  68. rev[tr[y][0]]^=1;
  69. }
  70. int main() {
  71. scanf("%d",&n);
  72. for (int i=1;i<=n;i++) scanf("%d",&a[i+1]);
  73. build(1,n+2,0);rt=(3+n)>>1;
  74. int ans=0;
  75. while (val[find(rt,2)]!=1) {
  76. ans++;
  77. rever(1,val[find(rt,2)]);
  78. if (ans>100000) {printf("-1");return 0;}
  79. }
  80. printf("%d",ans);
  81. return 0;
  82. }

  

  

【codevs1743】 反转卡片的更多相关文章

  1. [codevs1743]反转卡片

    [codevs1743]反转卡片 试题描述 [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同. 比如下图是N ...

  2. codevs 1743 反转卡片 rope or splay

    [codevs1743]反转卡片 题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数 ...

  3. codevs 1743 反转卡片

    题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同. 比如下图是N=5的一种 ...

  4. Codevs 1743 反转卡片(splay)

    1743 反转卡片 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N ...

  5. 【集训第四天·继续刷题】之 lgh怒刚ypj

    继续水题,终于完全掌握了伸展树了,好心痛QAQ. 1.codevs1343 蚱蜢 区间最大值查询+单点移动 最大值查询维护一个mx数组就行,单点移动么,先删除在插入 CODE: /* PS: 比较ma ...

  6. ●Splay的一些题

    ●个人感觉: 代码长: 函数多: (很套路): (很强的Splay,无愧于“区间王”) ●NOI2005维修数列 一个可以当模板学习的题,包含了众多操作(函数): 区间插入,删除,更新,翻转,询问信息 ...

  7. IOIOI卡片占卜(Atcoder-IOIOI カード占い)(最短路)

    题目描述: K 理事長は占いが好きで,いつも様々な占いをしている.今日は,表の面に ‘I’ が,裏の面に ‘O’ が書か れたカードを使って今年の IOI での日本選手団の出来を占うことにした. 占い ...

  8. 简谈百度坐标反转至WGS84的三种思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 基于百度地图进行数据展示是目前项目中常见场景,但是因为百度地图 ...

  9. .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整-控制反转和依赖注入的使用

    再次调整项目架构是因为和群友dezhou的一次聊天,我原来的想法是项目尽量做简单点别搞太复杂了,仅使用了DbContext的注入,其他的也没有写接口耦合度很高.和dezhou聊过之后我仔细考虑了一下, ...

随机推荐

  1. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

    概要 上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解Arra ...

  2. CefSharp的引用、配置、实例

    CefSharp的引用.配置.实例与报错排除(源码) Winform下CefSharp的引用.配置.实例与报错排除 本文详细介绍了CefSharp在vs2013..net4.0环境下,创建Winfro ...

  3. Android开篇(转)

    转自:http://gityuan.com/android/ 一.简述 Android系统非常庞大.错中复杂,其底层是采用Linux作为基底,上层采用包含虚拟机的Java层以及Native层,通过系统 ...

  4. Linux Linux程序练习十五(进程间的通信共享内存版)

    /* * 题目: * 编写程序,要去实现如下功能: 父进程创建子进程1和子进程2.子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2; 子进程2接受可靠信号的值,并发送给父进程,父进 ...

  5. shell 使用

    echo -e "1\t2\t3" #-e echo -e "\e[1;31m This is red text \e[0m" #color echo -e & ...

  6. iframe在ios下无故扩大的问题探究

    移动端页面内嵌了个 iframe,在 ios 下打开却发现页面怪异.比如 demo.代码如下: <!DOCTYPE html> <html lang="zh-CN" ...

  7. github开源:企业级应用快速开发框架CIIP WEB+WIN+移动端

    简介 CIIP是基于XAF开发的开源信息系统框架.CIIP最常见的应用场景是基于数据库的企业级应用程序,例如供应链系统,ERP系统,MRP系统,CRM系统等. CIIP支持WEB版本.Windows桌 ...

  8. HTTP 状态代码表示什么意思?

    HTTP 状态代码表示什么意思? 如果某项请求发送到您的服务器要求显示您网站上的某个网页,服务器将会返回 HTTP 状态码响应请求.此状态代码提供关于请求状态的信息,一些常见的状态代码为: 200 - ...

  9. 深入理解OOP(三):多态和继承(动态绑定和运行时多态)

    在前面的文章中,我们介绍了编译期多态.params关键字.实例化.base关键字等.本节我们来关注另外一种多态:运行时多态, 运行时多态也叫迟绑定. 深入理解OOP(一):多态和继承(初期绑定和编译时 ...

  10. Linux进程间通信之信号量

    春节过去了,真的过去一年了.在公司待了快一年了.2016希望自己变得越来越好. ps:上面那句话是年前写的,中间隔了那么久,自己也变懒了. 一.信号量 1,信号量本质是一个计数器,控制访问共享资源的最 ...