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写的,感觉很优秀。

代码

// codevs1743
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=300010;
int a[maxn],tr[maxn][2],fa[maxn],size[maxn],val[maxn],rev[maxn];
int n,ans,rt; void rotate(int x,int &k) {
int y=fa[x],z=fa[y],l,r;
if (x==tr[y][0]) l=0;else l=1;
r=l^1;
if (y==k) k=x;
else tr[z][tr[z][1]==y]=x;
fa[y]=x;fa[x]=z;fa[tr[x][r]]=y;
tr[y][l]=tr[x][r];tr[x][r]=y;
//注意这里一定先更新y的size,再更新x的size.
size[y]=size[tr[y][0]]+size[tr[y][1]]+1;
size[x]=size[tr[x][0]]+size[tr[x][1]]+1;
}
void splay(int x,int &k) {
while (x!=k) {
int y=fa[x],z=fa[y];
if (y!=k) { //如果x,y,z在一条链(形象)上,那么先旋y,再旋x.听说可以使平衡树更加平衡
if (tr[z][0]==y ^ tr[y][0]==z) rotate(x,k); //不在一条链上
else rotate(y,k); //在一条链上
}
rotate(x,k);
}
}
void pushdown(int k) {
int l=tr[k][0],r=tr[k][1];
rev[k]^=1;rev[l]^=1;rev[r]^=1; //如果同一个区间被反转2次,那么就等价于不反转.
swap(tr[k][0],tr[k][1]);
}
int find(int k,int x) { //在树中寻找序列中第rk个数
if (rev[k]) pushdown(k);
int l=tr[k][0],r=tr[k][1];
if (size[l]+1==x) return k;
else if (x<=size[l]) return find(l,x);
else return find(r,x-size[l]-1);
}
void build(int l,int r,int f) {
if (l>r) return;
int mid=(l+r)>>1;
//tr[][]记录当前节点的左儿子与右儿子
if (mid<f) tr[f][0]=mid;
else tr[f][1]=mid;
//size[]记录子树大小,val[]记录数值,fa[]记录父亲.
rev[mid]=0;val[mid]=a[mid];size[mid]=1;fa[mid]=f;
if (l==r) return;
build(l,mid-1,mid);
build(mid+1,r,mid);
size[mid]=size[tr[mid][0]]+size[tr[mid][1]]+1;
}
void rever(int l,int r) {
int x=find(rt,l),y=find(rt,r+2);
splay(x,rt);splay(y,tr[rt][1]);
rev[tr[y][0]]^=1;
}
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i+1]);
build(1,n+2,0);rt=(3+n)>>1;
int ans=0;
while (val[find(rt,2)]!=1) {
ans++;
rever(1,val[find(rt,2)]);
if (ans>100000) {printf("-1");return 0;}
}
printf("%d",ans);
return 0;
}

  

  

【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. JQuery常用方法(均实践过)

    1,使用jquery修改html元素的值 a,修改form的action的值(即修改html的属性值) 这个可以扩展为修改html元素的属性值的方法,使用的$("#id").att ...

  2. JS 中如何判断 undefined 和 null

    JS 中如何判断 undefined JavaScript 中有两个特殊数据类型:undefined 和 null,下节介绍了 null 的判断,下面谈谈 undefined 的判断. 以下是不正确的 ...

  3. Razor 模板自己渲染出结果 string

    using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNet ...

  4. [转]Linux日志文件总管——logrotate

    FROM : https://linux.cn/article-4126-1.html 日志文件包含了关于系统中发生的事件的有用信息,在排障过程中或者系统性能分析时经常被用到.对于忙碌的服务器,日志文 ...

  5. 学习C++.Primer.Plus 8 函数探幽

    1. 内联函数 普通函数调用: 存储调用指令的地址->将函数参数复制到堆栈->跳到函数地址执行代码(返回值放到寄存器)->跳回调用指令处 2.  当代码执行时间很短,且会被大量调用的 ...

  6. JSP中的Servlet及Filter

    asp.net中,如果开发人员想自己处理http请求响应,可以利用HttpHandler来满足这一要求:类似的,如果要拦截所有http请求,可以使用HttpMoudle.java的web开发中,也有类 ...

  7. JSON简介以及用法汇总

    什么是JSON? JavaScript 对象表示法(JavaScript Object Notation). JSON是一种轻量级的数据交换格式,某个JSON格式的文件内部譬如可以长成这样: { &q ...

  8. 利用uploadify+asp.net 实现大文件批量上传。

    前言 现在网上文件上传组件随便一搜都是一大堆,不过看大家一般都在用uploadify这个来上传文件.由于项目需要,我在来试了一下.因为第一次使用,也遇到了很多问题,特此记录! ------------ ...

  9. [BZOJ1854][Scoi2010]游戏(二分图匹配/并查集)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1854 分析:很裸的一道二分图匹配对吧,但是在hzwer的blog上看见神奇的并查集做法 ...

  10. 准确率(Accuracy), 精确率(Precision), 召回率(Recall)和F1-Measure

    yu Code 15 Comments  机器学习(ML),自然语言处理(NLP),信息检索(IR)等领域,评估(Evaluation)是一个必要的 工作,而其评价指标往往有如下几点:准确率(Accu ...