HihoCoder1677 : 翻转字符串(Splay)(区间翻转)
描述
给定一个字符串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)(区间翻转)的更多相关文章
- hihocoder 1677 翻转字符串 splay
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个字符串S,小Hi希望对S进行K次翻转操作. 每次翻转小Hi会指定两个整数Li和Ri,表示要将S[Li..Ri]进行 ...
- hdu-1890-Robotic Sort splay区间翻转
题意: 依次找第i大的数下标pos[i],然后将区间[i,pos[i]]翻转 分析: splay树区间翻转 // File Name: ACM/HDU/1890.cpp // Author: Zlbi ...
- bzoj 3223 文艺平衡树 splay 区间翻转
Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17715 Solved: 7769[Submit][Status][ ...
- bzoj 1251序列终结者 splay 区间翻转,最值,区间更新
序列终结者 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 4594 Solved: 1939[Submit][Status][Discuss] De ...
- BZOJ 3223 Splay区间翻转
思路: 区间翻转的裸题 终于tm理解splay了-- //By SiriusRen #include <cstdio> #include <cstring> #include ...
- splay区间翻转
原题P3391 [模板]文艺平衡树(Splay) 题目背景 这是一道经典的Splay模板题——文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: ...
- hdu1890 Robotic Sort (splay+区间翻转单点更新)
Problem Description Somewhere deep in the Czech Technical University buildings, there are laboratori ...
- 2019牛客国庆集训派对day1 K题 双向链表练习题 splay区间翻转
题目链接: 解法: 先建n颗平衡树,合并的时候将a中最右的结点翻转到根节点,b中最左的结点翻转到根节点,对合并后的根节点进行标记. #include <bits/stdc++.h> usi ...
- Splay(区间翻转)&树套树(Splay+线段树,90分)
study from: https://tiger0132.blog.luogu.org/slay-notes P3369 [模板]普通平衡树 #include <cstdio> #inc ...
- hdu 1890 Robotic Sort(splay 区间反转+删点)
题目链接:hdu 1890 Robotic Sort 题意: 给你n个数,每次找到第i小的数的位置,然后输出这个位置,然后将这个位置前面的数翻转一下,然后删除这个数,这样执行n次. 题解: 典型的sp ...
随机推荐
- 数据结构(Java语言)——Stack简单实现
栈是限制插入和删除仅仅能在一个位置上进行的表.该位置是表的末端,叫做栈的顶top.对栈的基本操作有进栈push和出栈pop,前者相当于插入.后者这是删除最后插入的元素. 栈有时又叫先进先出FIFO表. ...
- NUTCH2.3 hadoop2.7.1 hbase1.0.1.1 solr5.2.1部署(二)
Precondition: hadoop 2.7.1 hbase 1.0.1.1 / hbase 0.98.13 192.168.1.106 ->master 192.168.1.105 ...
- System.TypeLoadException: Could not load type 'System.IO.Compression.CompressionLevel' from assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
1.提示错误信息: zipSystem.TypeLoadException: Could not load type 'System.IO.Compression.CompressionLevel' ...
- 一步一步学ios UITextView(多行文本框)控件的用法详解(五5.8)
本文转载至 http://wuchaorang.2008.blog.163.com/blog/static/48891852201232014813990/ 1.创建并初始化 创建UIText ...
- delphi Base64编码/解码及数据压缩/解压知识
一.Base64编码/解码 一般用到的是Delphi自带的单元EncdDecd,当然还有第三方提供的单元或控件,其中我所接触到的认为比较好的有Indy的TIdMimeEncode / TIdMimeD ...
- sql中decode()重要函数使用
decode()函数简介: 主要作用:将查询结果翻译成其他值(即以其他形式表现出来,以下举例说明): 使用方法: Select decode(columnname,值1,翻译值1,值2,翻译值2,.. ...
- 九度OJ 1007:奥运排序问题 (排序)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7344 解决:1568 题目描述: 按要求,给国家进行排名. 输入: 有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号从0到N- ...
- 为什么需要onRoute函数?
为什么需要onRoute函数? · Tencent/wepy Wiki https://github.com/Tencent/wepy/wiki/%E4%B8%BA%E4%BB%80%E4%B9%88 ...
- QQ登录集成到自己网站php代码(转载)
我们现在在各大网站论坛都可以看到点击一个QQ图标就可以利用自己的QQ号在网站进行登录了,下面我来告诉你一段QQ登录集成到自己网站php代码,有需要的朋友可参考. 1.打开open.qq.com 添加创 ...
- Mongo 分组后排序取时间最大的一整条数据对象
db.getCollection('product_protocol_new').aggregate([ {$sort:{"end_date":-1}}, {$group:{ _i ...