[codevs1743]反转卡片

试题描述

【dzy493941464|yywyzdzr原创】

小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同。

比如下图是N=5的一种情况:3 4 2 1 5

接下来你需要按小A的要求反转卡片,使得左数第一张卡片上的数字是1。操作方法:令左数第一张卡片上的数是K,如果K=1则停止操作,否则将左数第1~K张卡片反转。

第一次(K=3)反转后得到:2 4 3 1 5

第二次(K=2)反转后得到:4 2 3 1 5

第三次(K=4)反转后得到:1 3 2 4 5

可见反转3次后,左数第一张卡片上的数变成了1,操作停止。

你的任务是,对于一种排列情况,计算要反转的次数。你可以假设小A不会让你操作超过100000次。

输入

第1行一个整数N

第2行N个整数,为1~N的一个全排列。

输出

仅1行,输出一个整数表示要操作的次数。

如果经过有限次操作仍无法满足要求,输出-1。

输入示例

    

输出示例


数据规模及约定

0<N≤300,000。

题解

还是暴力 splay 模拟。。。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 300010
#define maxq 100000
struct Node {
int siz; bool rev;
Node(): rev(0) {}
} ns[maxn];
int ToT, fa[maxn], ch[maxn][2], A[maxn];
void maintain(int o) {
ns[o].siz = 1;
for(int i = 0; i < 2; i++) if(ch[o][i])
ns[o].siz += ns[ch[o][i]].siz;
return ;
}
void build(int& o, int l, int r) {
if(l > r) return ;
int mid = l + r >> 1; o = A[mid];
build(ch[o][0], l, mid - 1); build(ch[o][1], mid + 1, r);
if(ch[o][0]) fa[ch[o][0]] = o;
if(ch[o][1]) fa[ch[o][1]] = o;
return maintain(o);
}
void pushdown(int o) {
for(int i = 0; i < 2; i++) if(ch[o][i])
ns[ch[o][i]].rev ^= ns[o].rev;
if(ns[o].rev) swap(ch[o][0], ch[o][1]), ns[o].rev = 0;
return ;
}
void rotate(int u) {
int y = fa[u], z = fa[y], l = 0, r = 1;
if(z) ch[z][ch[z][1]==y] = u;
if(ch[y][1] == u) swap(l, r);
fa[u] = z; fa[y] = u; fa[ch[u][r]] = y;
ch[y][l] = ch[u][r]; ch[u][r] = y;
maintain(y); maintain(u);
return ;
}
int S[maxn], top;
void splay(int u) {
int t = u; S[top = 1] = t;
while(fa[t]) t = fa[t], S[++top] = t;
while(top) pushdown(S[top--]);
while(fa[u]) {
int y = fa[u], z = fa[y];
if(z) {
if(ch[y][0] == u ^ ch[z][0] == y) rotate(u);
else rotate(y);
}
rotate(u);
}
return ;
}
int split(int u) {
if(!u) return splay(1), 1;
splay(u);
int tmp = ch[u][1];
fa[tmp] = ch[u][1] = 0;
return maintain(u), tmp;
}
int merge(int a, int b) {
if(!a) return b;
pushdown(a); while(ch[a][1]) a = ch[a][1], pushdown(a);
splay(a);
ch[a][1] = b; fa[b] = a;
return maintain(a), a;
}
int Find(int o, int k) {
pushdown(o);
if(!o) return 0;
int ls = ch[o][0] ? ns[ch[o][0]].siz : 0;
if(k == ls + 1) return o;
if(k > ls + 1) return Find(ch[o][1], k - ls - 1);
return Find(ch[o][0], k);
} int main() {
int n = read();
for(int i = 1; i <= n; i++) A[i] = read();
if(A[1] == 1) return puts("0"), 0; int tmp = 0, i; build(tmp, 1, n);
for(i = 1; i <= maxq; i++) {
splay(1);
int lrt = Find(1, Find(1, 1)), rrt = split(lrt);
ns[lrt].rev ^= 1;
lrt = merge(lrt, rrt);
if(Find(lrt, 1) == 1) break;
} printf("%d\n", i <= maxq ? i : -1); return 0;
}

[codevs1743]反转卡片的更多相关文章

  1. codevs 1743 反转卡片 rope or splay

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

  2. codevs 1743 反转卡片

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

  3. Codevs 1743 反转卡片(splay)

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

  4. 【codevs1743】 反转卡片

    http://codevs.cn/problem/1743/ (题目链接) 题意 给出一个序列{a1,a2,a3···},要求维护这样一种操作:将前a1个数反转,若第a1等于1,则停止操作. Solu ...

  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. 每天成长一点---WEB前端学习入门笔记

    WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...

  2. [LeetCode] Perfect Squares 完全平方数

    Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 1 ...

  3. [LeetCode] Find Peak Element 求数组的局部峰值

    A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ ...

  4. [LeetCode] Merge Intervals 合并区间

    Given a collection of intervals, merge all overlapping intervals. For example, Given [1,3],[2,6],[8, ...

  5. iOS开发中遇到的错误整理 - 集成第三方框架时,编译后XXX头文件找不到

    iOS编译报错-XXX头文件找不到 错误出现的情况: 自己在继承第三方的SDK的时候,明明导入了头文件,但是系统报错,提示头文件找不到 解决方法 既然系统找不到,给他个具体路径,继续找去! 路径就填写 ...

  6. 修改form表单的黄色背景

    input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset; }

  7. 《UNIX环境高级编程》笔记——1.UNIX基础知识

    这一章节侧重一些基本概念和书中用到的一些名词. 一.引言 所有的操作都提供服务,典型的服务包括:执行新程序.打开文件.读写文件.分配存储区以及获得当前时间等. 二.UNIX体系结构 其实linux常见 ...

  8. 页置换算法FIFO、LRU、OPT

    页置换算法FIFO.LRU.OPT 为什么需要页置换 在地址映射过程中,若在页面中发现所要访问的页面不再内存中,则产生缺页中断.当发生缺页中断时操作系统必须在内存选择一个页面将其移出内存,以便为即将调 ...

  9. 精通Web Analytics 2.0 (11) 第九章: 新兴分析—社交,移动和视频

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第九章: 新兴分析-社交,移动和视频 网络在过去几年中发生了不可思议的发展变化:从单向对话到双向对话的转变; 由视频,Ajax和 ...

  10. 使用stylelint对CSS/Sass做代码审查

    对样式审查?很少人会这么做吧,但实际上开发者应该有这样的态度,尤其是不同团队多人开发时,这一点尤为重要. 在本文中,我将陈述两点:一是为什么我们需要对样式进行审查,二是如何将审查工具融合到整体的构建流 ...