区间翻转(codevs 3243)
给出N个数,要求做M次区间翻转(如1 2 3 4变成4 3 2 1),求出最后的序列
第一行一个数N,下一行N个数表示原始序列,在下一行一个数M表示M次翻转,之后的M行每行两个数L,R表示将区间[L,R]翻转。
一行N个数 , 表示最终序列。
4
1 2 3 4
2
1 2
3 4
2 1 4 3
对于30%的数据满足n<=100 , m <= 10000
对于100%的数据满足n <= 150000 , m <= 150000
对于100%的数据满足n为2的幂,且L = i * 2^j + 1 , R = (i + 1) * 2^j
最初自己写了一个,然后怎么调也调不出来,明天再战:
#include<cstdio>
#include<iostream>
#define N 150010
using namespace std;
int son[N][],fa[N],val[N],order[N],rev[N],sz[N],n,m,rt,size;
void pushup(int x){
if(!x)return;
sz[x]=sz[son[x][]]+sz[son[x][]]+;
}
void pushdown(int x){
swap(son[x][],son[x][]);
rev[son[x][]]^=;rev[son[x][]]^=;
rev[x]^=;
}
void rotate(int x,int &k){
int y=fa[x],z=fa[y],l,r;
if(son[y][]==x)l=;else l=;r=l^;
if(y==k)k=x;
else {
if(son[z][]==y) son[z][]=x;
else son[z][]=x;
}
fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x,int &k){
while(x!=k){
int y=fa[x],z=fa[y];
if(y!=k){
if((son[y][]==x)^(son[z][]==y)) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
void insert(int hao,int v){
int k=rt,y=;
while(k)y=k,k=son[k][hao>order[k]];
k=++size;fa[k]=y;son[y][v>order[y]]=k;val[k]=v;order[k]=hao;sz[k]=;
splay(k,rt);
}
int find(int x){
int k=rt;
while(){
if(rev[k])pushdown(k);
if(sz[son[k][]]+==x)return k;
if(sz[son[k][]]>=x) k=son[k][];
else x-=(sz[son[k][]]+),k=son[k][];
}
}
void rever(int x,int y){
if(x==&&y==n)rev[rt]^=;
if(x==&&y<n){
int p=find(y+);
splay(p,rt);rev[son[rt][]]^=;
}
if(y==n&&x>){
int p=find(x-);
splay(p,rt);rev[son[rt][]]^=;
}
if(x>&&y<n){
int p;
p=find(x-);splay(p,rt);
p=find(y+);splay(p,son[rt][]);
rev[son[son[rt][]][]]^=;
}
}
void dfs(int k){
if(!k)return;
if(rev[k])pushdown(k);
dfs(son[k][]);
printf("%d ",val[k]);
dfs(son[k][]);
}
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
int x;scanf("%d",&x);
insert(i,x);
}
scanf("%d",&m);
for(int i=;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
//if(i==1)continue;
rever(x,y);
}
dfs(rt);
return ;
}
比着黄学长写了一个:
#include<cstdio>
#include<iostream>
#define N 150010
using namespace std;
int fa[N],son[N][],id[N],sz[N],rev[N],val[N];
int n,m,size,rt;
void pushup(int k){
int l=son[k][],r=son[k][];
sz[k]=sz[l]+sz[r]+;
}
void pushdown(int k){
int l=son[k][],r=son[k][];
if(rev[k]){
swap(son[k][],son[k][]);
rev[l]^=;rev[r]^=;
rev[k]=;
}
}
void rotate(int x,int &k){
int y=fa[x],z=fa[y],l,r;
if(son[y][]==x)l=;else l=;r=l^;
if(y==k)k=x;
else {
if(son[z][]==y) son[z][]=x;
else son[z][]=x;
}
fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
pushup(y);pushup(x);
}
void splay(int x,int &k){
while(x!=k){
int y=fa[x],z=fa[y];
if(y!=k){
if((son[y][]==x)^(son[z][]==y)) rotate(x,k);
else rotate(y,k);
}
rotate(x,k);
}
}
int find(int k,int rank){
pushdown(k);
int l=son[k][],r=son[k][];
if(sz[l]+==rank)return k;
else if(sz[l]>=rank) return find(l,rank);
else return find(r,rank-sz[l]-);
}
void rever(int l,int r){
int x=find(rt,l),y=find(rt,r+);
splay(x,rt);splay(y,son[x][]);
int z=son[y][];rev[z]^=;
}
void build(int l,int r,int f){
if(l>r)return;
int now=id[l],last=id[f];
if(l==r){
fa[now]=last;sz[now]=;
if(l<f)son[last][]=now;
else son[last][]=now;
return;
}
int mid=l+r>>;now=id[mid];
build(l,mid-,mid);build(mid+,r,mid);
fa[now]=last;pushup(mid);
if(mid<f)son[last][]=now;
else son[last][]=now;
}
int main(){
scanf("%d",&n);
for(int i=;i<=n+;i++)
id[i]=++size;
val[]=-0x7fffffff;val[n+]=0x7fffffff;
for(int i=;i<=n+;i++)
scanf("%d",&val[i]);
build(,n+,);rt=(n+)>>;
scanf("%d",&m);
for(int i=;i<=m;i++){
int l,r;scanf("%d%d",&l,&r);
rever(l,r);
}
for(int i=;i<=n+;i++)
printf("%d ",val[find(rt,i)]);
return ;
}
区间翻转(codevs 3243)的更多相关文章
- [BZOJ 3223 & Tyvj 1729]文艺平衡树 & [CodeVS 3243]区间翻转
题目不说了,就是区间翻转 传送门:BZOJ 3223 和 CodeVS 3243 第一道题中是1~n的区间翻转,而第二道题对于每个1~n还有一个附加值 实际上两道题的思路是一样的,第二题把值对应到位置 ...
- WIKIOI 3243 区间翻转
3243 区间翻转 题目描述 Description 给出N个数,要求做M次区间翻转(如1 2 3 4变成4 3 2 1),求出最后的序列 输入描述 Input Description 第一行一个数N ...
- CODEVS 4655 序列终结者-splay(区间更新、区间翻转、区间最值)
4655 序列终结者 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 题目描述 Description 网上有许多题,就是给定一个序列,要 ...
- codevs3243 区间翻转
题目描述 Description 给出N个数,要求做M次区间翻转(如1 2 3 4变成4 3 2 1),求出最后的序列 输入描述 Input Description 第一行一个数N,下一行N个数表示原 ...
- hdu-3487-Play with Chain-(splay 区间翻转,切割,插入)
题意: 区间翻转,切割,插入 // File Name: ACM/HDU/3487.cpp // Author: Zlbing // Created Time: 2013年08月10日 星期六 21时 ...
- hdu-1890-Robotic Sort splay区间翻转
题意: 依次找第i大的数下标pos[i],然后将区间[i,pos[i]]翻转 分析: splay树区间翻转 // File Name: ACM/HDU/1890.cpp // Author: Zlbi ...
- bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2202 Solved: 1226[Submit][Sta ...
- [置顶] hdu 1890 伸展树区间翻转
题意: 给你n个数,每次先输出第i大的数的位置(如果有多个,选下标小的那个),然后每次将第i个位置到第i大的数所在位置之间的数进行翻转. 思路:输入的数组可能有多个相同的值,我们可以进行两次排序把数组 ...
- hdu3397区间覆盖,区间翻转,区间合并,区间求和
调了很久的代码..注意区间翻转和覆盖的操作互相的影响 /* 区间替换操作怎么搞? 应该是加个tag标记 如果整个区间都是0|1,那么把若有tag的话直接set1|0即可,也不用设置tag标记 反之要设 ...
随机推荐
- nyoj-1103-区域赛系列一多边形划分
http://acm.nyist.net/JudgeOnline/problem.php?pid=1103 区域赛系列一多边形划分 时间限制:1000 ms | 内存限制:65535 KB 难度: ...
- tomcat假死现象 - 二
1 编写背景 最近服务器发现tomcat的应用会偶尔出现无法访问的情况.经过一段时间的观察最近又发现有台tomcat的应用出现了无法访问情况.简单描述下该台tomcat当时具体的表现:客户端请求没有响 ...
- Use-After-Free
0x00 UAF利用原理 uaf漏洞产生的主要原因是释放了一个堆块后,并没有将该指针置为NULL,这样导致该指针处于悬空的状态(这个指针可以称为恶性迷途指针),同样被释放的内存如果被恶意构造数据,就有 ...
- HibernateDaoSupport类的底层中hql操作使用
spring的ApplicationContex.xml 中配置 sql 查询方法: 加载数据源的两种方式: <!--方式一:使用 c3p0 连接池 加载数据源 --> <bean ...
- OmniFocus
褪墨・时间管理 “把所有事情都从你的脑袋里弄出来.在事情出现就做好相关行动的一系列决定,而不是在事情爆发的时候.以合适的类别组织好你的项目的各种提醒以及下一步行动.保持你的系统更新和完整,及时进行回顾 ...
- 将 PROTOCOL 的方法声明为 MUTATING
将 PROTOCOL 的方法声明为 MUTATING 由 王巍 (@ONEVCAT) 发布于 2014/08/17 Swift 的 protocol 不仅可以被 class 类型实现,也适用于 str ...
- NOIP 2018数据点
链接: https://pan.baidu.com/s/14jXQGPSac3b9_m5h5x2wGQ 提取码: 1cbk 好文别忘点赞!!!
- [LUOGU] P1049 装箱问题
题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱内,使箱子的剩余 ...
- (11)zabbix item types监控类型
1. 什么是item types item types是由zabbix提供的各种类型的检查器(这样翻译很奇怪),大致就是Zabbix agent, Simple checks, SNMP, Zabbi ...
- perl学习之:匹配修饰符/s /m
m 是将字符串作为多行处理,s是将字符串作为单行处理,如果是s在字符串中出现的\n就相当于普通字符. 6.6. Matching Within Multiple Lines6.6.1. Problem ...