描述

给定一个字符串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. WinForm搭载ScintillaNET时文本由于发生偏移被隐藏解决方案

    项目用ScintillaNet搭载到WinForm以满足文本编辑的需求,在用FindReplace.Scintilla.Text=“显示内容”输出文本内容的时候会碰到文本被WinForm边框隐藏的情况 ...

  2. robotframework安装appium

    安装: Appium-Python-Client,在运行的cmd下输入:pip install Appium-python-Client 安装:robotframework-appiumlibrary ...

  3. linux下安装redis报错问题。

    1.使用tar -xzvf redis-2.4.5.tar.gz来解压安装包 2.使用make命令来编译Redis 如果出现错误需要查看是否缺少gcc gcc-c++ zmalloc.h:50:31: ...

  4. Android 属性动画框架 ObjectAnimator、ValueAnimator ,这一篇就够了

    前言 我们都知道 Android 自带了 Roate Scale Translate Alpha 多种框架动画,我们可以通过她们实现丰富的动画效果,但是这些宽家动画却有一个致命的弱点,它们只是改变了 ...

  5. 开源监控软件ganglia

    开源监控软件ganglia安装手册 Ganglia是一个监控服务器,集群的开源软件,能够用曲线图表现最近一个小时,最近一天,最近一周,最近一月,最近一年的服务器或者集群的cpu负载,内存,网络,硬盘等 ...

  6. 献给写作者的 Markdown 新手指南及语法

    烈推荐所有写作者学习和掌握该语言.为什么?可以参考: 『为什么作家应该用 Markdown 保存自己的文稿』. 『Markdown写作浅谈』 让你专注于文字而不是排版. 标题 只需要在文本前面加上 # ...

  7. U盘中毒变成exe快捷键文件不见问题

    大家好,大家能够叫我阿胜,今天给我大家带一个有用小方法,希望对大家有帮助.去学校打印社打印东西,U盘中病毒,使U盘文件所有变成快捷键了,这个坑爹的打印社.这时我该怎么办......    嘿嘿.阿胜给 ...

  8. eclipse如何debug调试jdk源码

    java是一门开源的程序设计语言,喜欢研究源码的java开发者总会忍不住debug一下jdk源码.虽然官方的jdk自带了源码包src.zip,然而在debug时查看变量却十分麻烦.例如调试HashMa ...

  9. oc中 中文到拼音的转换

    偶然发现的一个好玩的功能

  10. 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包

    [BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...