Splay

适用题目特征

维护区间翻转。

原理

想要翻转区间[l,r],只要将Splay重构如下。

区间翻转

并且在每次操作后,都模仿类似线段树lazy标记,下传区间翻转标记即可。
PS:Splay实现时,通常需要加入首尾两个节点来处理边界情况,所以最终处理书上相关操作时,都要考虑这个两个节点。

例题

Luogu P3391
代码如下

/*
Luogu P3391
*/
#define method_2
#ifdef method_1
/*

*/

#endif
#ifdef method_2
/*

*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<"  "
#define E cout<<endl
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rep0(i,s,t) for(int i=(s);i<(t);i++)
#define rrep(i,t,s) for(int i=(t);i>=(s);i--)
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
int n,m;
int a[maxn];
struct Splay{
    int sz,tag,f,son[2],val;
}s[maxn];
int rt;
#define pushup(x) (s[x].sz=s[s[x].son[0]].sz+s[s[x].son[1]].sz+1)
#define rever(x) (swap(s[x].son[0],s[x].son[1]),s[x].tag^=1)
#define pushdown(x) (s[x].tag&&(rever(s[x].son[0]),rever(s[x].son[1]),s[x].tag=0))
#define which(x) (s[s[x].f].son[1]==x)
#define connect(x,y,d) (s[s[x].f=y].son[d]=x)
#define split(x,y) (splay(find(x),rt),splay(find((y)+2),s[rt].son[1]),s[s[rt].son[1]].son[0])
inline void rotate(int x,int& k){
    register int fa=s[x].f,pa=s[fa].f,d=which(x);pushdown(fa),pushdown(x),
    (fa^k?s[pa].son[which(fa)]=x:k=x),s[x].f=pa,connect(s[x].son[d^1],fa,d),connect(fa,x,d^1),pushup(fa),pushup(x);
}
inline void splay(int x,int& k) {int fa;while(x^k) fa=s[x].f,fa^k&&(rotate(which(x)^which(fa)?x:fa,k),0),rotate(x,k);}
inline void build(int l,int r,int& rt){
    int mid=l+r>>1;
    if(s[rt=mid].sz=1,s[rt].val=a[mid],!(l^r)) return;
    l<mid&&(build(l,mid-1,s[rt].son[0]),s[s[rt].son[0]].f=rt),
    r>mid&&(build(mid+1,r,s[rt].son[1]),s[s[rt].son[1]].f=rt),
    pushup(rt);
}
inline int find(int rk){
    int x=rt;
    while(x) {
        if(pushdown(x),s[s[x].son[0]].sz>=rk) x=s[x].son[0];
        else if(!(rk-=s[s[x].son[0]].sz+1)) return x;
        else x=s[x].son[1];
    }
}
inline void reverse(int l,int r){
    int k=split(l,r);rever(k);
}
void dfs(int x){
    pushdown(x);
    if(s[x].son[0]) dfs(s[x].son[0]);
    if(s[x].val!=-INF&&s[x].val!=INF) printf("%d ",s[x].val);
    if(s[x].son[1]) dfs(s[x].son[1]);
}
void solve(){
    build(1,n+2,rt);
    rep(x,2,n+1){
        int l,r;scanf("%d%d",&l,&r);
        reverse(l,r);
    }
    dfs(rt);
}
int main() {
//  ios::sync_with_stdio(false);
//  freopen("文艺平衡树.in","r",stdin);
    scanf("%d%d",&n,&m);
    a[1]=-INF,a[n+2]=INF;
    int x;
    rep(i,1,n) a[i+1]=i;
    solve();
    return 0;
}
#endif
#ifdef method_3
/*

*/

#endif

Luogu P4402
代码如下

/*
Luogu P4402 
*/
#define method_1
#ifdef method_1
/*

*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<ctime>
#include<string>
#include<bitset>
#define D(x) cout<<#x<<" = "<<x<<"  "
#define E cout<<endl
#define rep(i,s,t) for(int i=(s);i<=(t);i++)
#define rep0(i,s,t) for(int i=(s);i<(t);i++)
#define rrep(i,t,s) for(int i=(t);i>=(s);i--)
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int maxn=100000+5;
const int INF=0x3f3f3f3f;
int n;
struct s{
    int id,val;
    bool operator<(const s &h)const{return val<h.val||(val==h.val&&id<h.id);}
}a[maxn];
struct Splay{
    int sz,tag,f,son[2];
}s[maxn];
int rt;
#define pushup(x) (s[x].sz=s[s[x].son[0]].sz+s[s[x].son[1]].sz+1)
#define rever(x) (swap(s[x].son[0],s[x].son[1]),s[x].tag^=1)
#define pushdown(x) (s[x].tag&&(rever(s[x].son[0]),rever(s[x].son[1]),s[x].tag=0))
#define which(x) (s[s[x].f].son[1]==x)
#define connect(x,y,d) (s[s[x].f=y].son[d]=x)
#define split(x,y) (splay(find(x),rt),splay(find((y)+2),s[rt].son[1]),s[s[rt].son[1]].son[0])
inline void rotate(int x,int& k){
    register int fa=s[x].f,pa=s[fa].f,d=which(x);pushdown(fa),pushdown(x),
    (fa^k?s[pa].son[which(fa)]=x:k=x),s[x].f=pa,connect(s[x].son[d^1],fa,d),connect(fa,x,d^1),pushup(fa),pushup(x);
}
inline void splay(int x,int& k) {int fa;while(x^k) fa=s[x].f,fa^k&&(rotate(which(x)^which(fa)?x:fa,k),0),rotate(x,k);}
inline void build(int l,int r,int& rt){
    int mid=l+r>>1;
    if(s[rt=mid].sz=1,!(l^r)) return;
    l<mid&&(build(l,mid-1,s[rt].son[0]),s[s[rt].son[0]].f=rt),
    r>mid&&(build(mid+1,r,s[rt].son[1]),s[s[rt].son[1]].f=rt),
    pushup(rt);
}
inline int find(int rk){
    int x=rt;
    while(x) {
        if(pushdown(x),s[s[x].son[0]].sz>=rk) x=s[x].son[0];
        else if(!(rk-=s[s[x].son[0]].sz+1)) return x;
        else x=s[x].son[1];
    }
}
inline void reverse(int l,int r){
    int k=split(l,r);rever(k);
}
void solve(){
    sort(a+2,a+n+2);
    build(1,n+2,rt);
    rep(x,2,n+1){
        splay(a[x].id+1,rt);
        int ans=s[s[rt].son[0]].sz;printf("%d ",ans);
        reverse(x-1,ans);
    }
}
int main() {
//  ios::sync_with_stdio(false);
//  freopen("机械排序.in","r",stdin);
    scanf("%d",&n);
    a[1].val=-INF,a[n+2].val=INF;
    a[1].id=-INF,a[n+2].id=INF;
    int x;
    rep(i,1,n) scanf("%d",&x),a[i+1].id=i,a[i+1].val=x;
    solve();
    return 0;
}
#endif
#ifdef method_2
/*

*/

#endif
#ifdef method_3
/*

*/

#endif
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容