描述

给定一个字符串S,小Hi希望对S进行K次翻转操作。

每次翻转小Hi会指定两个整数Li和Ri,表示要将S[Li..Ri]进行翻转。(S下标从0开始,即S[0]是第一个字母)

例如对于S="abcdef",翻转S[2..3] 得到S="abdcef";再翻转S[0..5]得到S="fecdba"。

输入

第一行包含一个由小写字母组成的字符串S。

第二行包含一个整数K。

以下K行每行包含两个整数Li和Ri。

对于50%的数据,1 ≤ |S| ≤ 1000

对于100%的数据,1 ≤ |S| ≤ 100000, 1 ≤ K ≤ 100000, 0 ≤ Li ≤ Ri < |S|

输出

输出经过K次翻转后的字符串S

样例输入

abcdef
2
2 3
0 5

样例输出

fecdba

比赛的时候以为可以用lazy下压标记,但是后面lazy失去了作用。这道题不能用线段树做的原因不是因为数据范围,而是这道题涉及到了翻转操作,线段树不支持这种操作,所以用splay来维护。

现在模板初步成型。

对于初始值:

  • 如果是插入和查询一起操作,那就按顺序来。
  • 否则,初始时,二分建树。不然一个一个加,会成一条链,然后N^2爆炸。

对于区间:

  • 可能是有id的,对id在[L,R]之间进行操作,则查找L的前一个点,和R的后一个点,然后操作。(即find函数)
  • 也可能没有id,对当前队伍的从前往后的第[L,R]th之间进行操作,则先查找第L大...。(即findkth函数)
  • 如果存在反转rev操作,也只能用查找第k大来得到区间(上面第二种)。
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=;
const int inf=;
char c[maxn];int n;
struct SplayTree
{
int ch[maxn][],fa[maxn],rev[maxn],sz[maxn];
int cnt,root;
void init()
{
cnt=; root=(+n+)>>;
}
void build(int L,int R,int pre)
{
if(L>R) return ;//build不同于线段树,这里有可能大于。
if(L==R) {
fa[L]=pre;sz[L]=;
ch[pre][L>=pre]=L;
return ;
}int Mid=(L+R)>>;
build(L,Mid-,Mid);build(Mid+,R,Mid);//这里好像有点乱
fa[Mid]=pre; pushup(Mid);
ch[pre][Mid>=pre]=Mid;
}
void pushup(int x)
{
sz[x]=;
if(ch[x][]) sz[x]+=sz[ch[x][]];
if(ch[x][]) sz[x]+=sz[ch[x][]];
}
void pushdown(int x)
{
if(!rev[x]) return ;
swap(ch[x][],ch[x][]);
rev[ch[x][]]^=;rev[ch[x][]]^=;
rev[x]=;
}
int find(int x,int rk)//ok
{
pushdown(x);//莫忘
if(sz[ch[x][]]==rk-) return x;
if(sz[ch[x][]]>=rk) return (find(ch[x][],rk));
return find(ch[x][],rk-sz[ch[x][]]-);
}
void rotate(int x,int opt)//ok
{
int y=fa[x],z=fa[y];
pushdown(y);pushdown(x);
if(z!=) ch[z][ch[z][]==y]=x;fa[x]=z;
ch[y][opt]=ch[x][opt^];fa[ch[x][opt^]]=y;
ch[x][opt^]=y;fa[y]=x;
pushup(y);
}
void splay(int x,int y)//把x移到y下面
{
pushdown(x);
while(fa[x]!=y){
int f=fa[x],ff=fa[f];
int c1=(ch[f][]==x),c2=(ch[ff][]==f);//记录c1 c2,因为rotate之后儿子关系会改变。
if(ff==y) rotate(x,c1);
else {
if(c1^c2) rotate(x,c1),rotate(x,c2);
else rotate(f,c2),rotate(x,c1);
}
} pushup(x); if(!y) root=x;//提到root
}
void revers(int L,int R)
{
int x=find(root,L-),y=find(root,R+);
splay(x,); splay(y,x);
rev[ch[y][]]^=;
}
void print(int x)
{
pushdown(x);
if(ch[x][]) print(ch[x][]);
if(x>=&&x<=n+) printf("%c",c[x]);
if(ch[x][]) print(ch[x][]);
}
}Tree;
int main()
{
int i,m,L,R;scanf("%s",c+);
n=strlen(c+);Tree.init();//莫忘了初始root
Tree.build(,n+,); scanf("%d",&m);
for(i=;i<=m;i++){
scanf("%d%d",&L,&R);
Tree.revers(L+,R+);
} Tree.print(Tree.root);
return ;
}

HihoCoder1677 : 翻转字符串(Splay)(区间翻转)的更多相关文章

  1. hihocoder 1677 翻转字符串 splay

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个字符串S,小Hi希望对S进行K次翻转操作. 每次翻转小Hi会指定两个整数Li和Ri,表示要将S[Li..Ri]进行 ...

  2. hdu-1890-Robotic Sort splay区间翻转

    题意: 依次找第i大的数下标pos[i],然后将区间[i,pos[i]]翻转 分析: splay树区间翻转 // File Name: ACM/HDU/1890.cpp // Author: Zlbi ...

  3. bzoj 3223 文艺平衡树 splay 区间翻转

    Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 17715  Solved: 7769[Submit][Status][ ...

  4. bzoj 1251序列终结者 splay 区间翻转,最值,区间更新

    序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 4594  Solved: 1939[Submit][Status][Discuss] De ...

  5. BZOJ 3223 Splay区间翻转

    思路: 区间翻转的裸题 终于tm理解splay了-- //By SiriusRen #include <cstdio> #include <cstring> #include ...

  6. splay区间翻转

    原题P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: ...

  7. hdu1890 Robotic Sort (splay+区间翻转单点更新)

    Problem Description Somewhere deep in the Czech Technical University buildings, there are laboratori ...

  8. 2019牛客国庆集训派对day1 K题 双向链表练习题 splay区间翻转

    题目链接: 解法: 先建n颗平衡树,合并的时候将a中最右的结点翻转到根节点,b中最左的结点翻转到根节点,对合并后的根节点进行标记. #include <bits/stdc++.h> usi ...

  9. Splay(区间翻转)&树套树(Splay+线段树,90分)

    study from: https://tiger0132.blog.luogu.org/slay-notes P3369 [模板]普通平衡树 #include <cstdio> #inc ...

  10. hdu 1890 Robotic Sort(splay 区间反转+删点)

    题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...

随机推荐

  1. SQLAlchemy使用笔记--SQLAlchemy ORM(三)

    參考: http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#eager-loading 预先载入 前面的代码,由于是lazy load.当我 ...

  2. AspectJ学习笔记2-Eclipse中AspectJ插件AJDT的正确安装方法

    接着之前一篇日志. 这个事情也挺无语的.简单记录一下. 在这里:http://www.eclipse.org/ajdt/ 能够下载最新的Eclipse Plugin.下载解压之后,一般来说.直接把解压 ...

  3. 30天自制操作系统(三)进入32位模式并导入C语言

    1 制作真正的IPL IPL(Initial Program Loader),启动程序装载器,但是之前并没有实质性的装载任何程序,这次作者要开始装载程序了. 虽然现在开发的操作系统啥功能也没有,作者说 ...

  4. Ubuntu 14.04lts安装vncserver

    之前有在centos上安装过非常多次vncserver,也写过一个centos 7上的安装文档.近来常识了好几次在ubuntu上安装都没有成功,这次最终搞定了.ubuntu自带的桌面是unity.这个 ...

  5. 07 redi sorder set结构及命令详解

    zadd key score1 value1 score2 value2 .. 添加元素 redis 127.0.0.1:6379> zadd stu 18 lily 19 hmm 20 lil ...

  6. 图像处理之基础---二维卷积c实现

    http://wenku.baidu.com/link?url=4RzdmvP9sdaaUbnVEW4OyBD-g67wIOiJjKFF3Le_bu7hIiBS7I6hMcDmCXrQwsHvrsPv ...

  7. ASP.NET动态网站制作(2)--css(1)

    前言:这节课主要讲关于css的相关内容. 重点:1.css(Cascading Style Sheet)叠层样式表,做网页的外观,是用来控制网页样式并允许将样式信息与网页内容分离的一种标记性语言. 2 ...

  8. 自动关闭AfxMessageBox对话框―模拟"回车" VC

    有的时候,在程序里面调用太多的AfxMessageBox(非调试用),弹出的对话框要手动关闭,时间一长就感觉很繁琐.于是上网找了一些资料,发现有一个很简单的实现AfxMessageBox对话框自动关闭 ...

  9. vs2013 solution文件解析

    1 定义一个project Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "render", &quo ...

  10. Flask的Debug功能非常酷

    Flask是一个Python开发框架.在试用的过程中发现它的debug功能非常cool.如下图所示,在出错的页面每条栈新的右边都有一个按钮,点击之后我们可以执行Python代码,而且非常重要的一点是通 ...