【codevs1743】 反转卡片
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】 反转卡片的更多相关文章
- [codevs1743]反转卡片
[codevs1743]反转卡片 试题描述 [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同. 比如下图是N ...
- codevs 1743 反转卡片 rope or splay
[codevs1743]反转卡片 题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数 ...
- codevs 1743 反转卡片
题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同. 比如下图是N=5的一种 ...
- Codevs 1743 反转卡片(splay)
1743 反转卡片 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 大师 Master 题目描述 Description [dzy493941464|yywyzdzr原创] 小A将N ...
- 【集训第四天·继续刷题】之 lgh怒刚ypj
继续水题,终于完全掌握了伸展树了,好心痛QAQ. 1.codevs1343 蚱蜢 区间最大值查询+单点移动 最大值查询维护一个mx数组就行,单点移动么,先删除在插入 CODE: /* PS: 比较ma ...
- ●Splay的一些题
●个人感觉: 代码长: 函数多: (很套路): (很强的Splay,无愧于“区间王”) ●NOI2005维修数列 一个可以当模板学习的题,包含了众多操作(函数): 区间插入,删除,更新,翻转,询问信息 ...
- IOIOI卡片占卜(Atcoder-IOIOI カード占い)(最短路)
题目描述: K 理事長は占いが好きで,いつも様々な占いをしている.今日は,表の面に ‘I’ が,裏の面に ‘O’ が書か れたカードを使って今年の IOI での日本選手団の出来を占うことにした. 占い ...
- 简谈百度坐标反转至WGS84的三种思路
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 基于百度地图进行数据展示是目前项目中常见场景,但是因为百度地图 ...
- .Net Core MVC 网站开发(Ninesky) 2.3、项目架构调整-控制反转和依赖注入的使用
再次调整项目架构是因为和群友dezhou的一次聊天,我原来的想法是项目尽量做简单点别搞太复杂了,仅使用了DbContext的注入,其他的也没有写接口耦合度很高.和dezhou聊过之后我仔细考虑了一下, ...
随机推荐
- 根据Unicode编码用C#语言把它转换成汉字的代码
rt 根据所具有的Unicode编码用C#语言把它转换成汉字的代码 var s = System.Web.HttpUtility.HtmlDecode(Utf8Str); var o = Newton ...
- windows Server 2008各版本区别详解
Windows Server 2008 是专为强化下一代网络.应用程序和 Web 服务的功能而设计,是有史以来最先进的 Windows Server 操作系统.拥有 Windows Server 20 ...
- 032医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------Service层和Action层和调试
我们上一篇文章讲了Dao层代码: 这一篇我们讲解Service层和Action层: Service层: 分为接口和实现类,我们主要看实现类:GysemplServiceImpl package yyc ...
- 使用spring boot+mybatis+mysql 构建RESTful Service
开发目标 开发两个RESTful Service Method Url Description GET /article/findAll POST /article/insert 主要使用到的技术 j ...
- JS使构造函数与new操作符无关
function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash; } 当使用User函数创 ...
- windows命令行下简单使用javac、java、javap详细演示
最近重新复习了一下java基础,在使用javap的过程中遇到了一些问题,这里便讲讲对于一个类文件如何编译.运行.反编译的.也让自己加深一下印象. 如题,首先我们在桌面,开始->运行->键入 ...
- 【福吧资源网整理】老男孩-python运维6期 不加密
老男孩-python运维6期 不加密,连夜整理出来分享给大家老男孩的python教程确实不错. 教程目录: 下载地址:http://www.fu83.cn/thread-204-1-1.html
- FineUI v4.0.2 (beta) 发布了!
FineUI v4.0.2 (beta) 已经于 2013-12-15 发布! ================================== 关于FineUI基于 ExtJS 的开源 ASP. ...
- ASP.NET - SqlSugar ORM框架 更新列表
以后SqlSugar所有更新都会在这个贴子更新 SqlSugar是一款轻量级的MSSQL ORM ,除了具有媲美ADO的性能外还具有和EF相似简单易用的语法. 学习列表 0.功能更新 1.SqlSug ...
- 如何批量删除虚拟机及其关联的存储(Windows Azure)
可以通过运行附件中PowerShell脚本文件RemoveVMandDisk.ps1批量删除VM和Disk,详细代码如下: param($serviceName) echo "Startin ...