bzoj3580

非旋转treap

在大神教导下发现split一段区间时先split右边再split左边比较好写

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
using namespace std;
typedef long long LL;
const int M=200007;
inline int rd(){
    int x=0;bool f=1;char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=0;
    for(;isdigit(c);c=getchar())x=x*10-48+c;
    return f?x:-x;
}

struct D{
    int c[2];
    D(){c[0]=c[1]=0;}
};

struct treap{
    int sz,val,fix,mn,rev,tag,c[2];
    void input(){
        val=mn=rd();
        fix=rand();
        sz=1;
        rev=tag=c[0]=c[1]=0;
    }
}a[M];

int n,m,rt;

inline int min(int x,int y){
    return x<y?x:y;
}

void update(int x){
    a[x].mn=a[x].val,a[x].sz=1;
    if(a[x].c[0]) a[x].mn=min(a[x].mn,a[a[x].c[0]].mn),a[x].sz+=a[a[x].c[0]].sz;
    if(a[x].c[1]) a[x].mn=min(a[x].mn,a[a[x].c[1]].mn),a[x].sz+=a[a[x].c[1]].sz;
}

void totag(int x,int z){
    a[x].tag+=z;
    a[x].mn+=z;
    a[x].val+=z;
}

void pushdown(int x){
    if(a[x].rev){
        if(a[x].c[0])a[a[x].c[0]].rev^=1;
        if(a[x].c[1])a[a[x].c[1]].rev^=1;
        a[x].rev^=1;
        swap(a[x].c[0],a[x].c[1]);
    }
    if(a[x].tag){
        if(a[x].c[0]) totag(a[x].c[0],a[x].tag);
        if(a[x].c[1]) totag(a[x].c[1],a[x].tag);
        a[x].tag=0;
    }
}

int build(int l,int r){
    if(l>r) return 0;
    int mid=l+r>>1;
    a[mid].c[0]=build(l,mid-1);
    a[mid].c[1]=build(mid+1,r);
    update(mid);
    return mid;
}

D split(int x,int k){
    D nw;
    if(x==0)return nw;
    pushdown(x);
    if(a[a[x].c[0]].sz+1==k){
        nw.c[1]=a[x].c[1];
        a[x].c[1]=0;
        nw.c[0]=x;
    }
    else if(k<=a[a[x].c[0]].sz){
        nw=split(a[x].c[0],k);
        a[x].c[0]=nw.c[1];
        nw.c[1]=x;
    }
    else{
        nw=split(a[x].c[1],k-a[a[x].c[0]].sz-1);
        a[x].c[1]=nw.c[0];
        nw.c[0]=x;
    }
    update(x);
    return nw;
}

int merge(int x,int y){
    if(!x) return y;
    if(!y) return x;
    if(a[x].fix<a[y].fix){
        pushdown(x);
        a[x].c[1]=merge(a[x].c[1],y);
        update(x);
        return x;
    }
    else{
        pushdown(y);
        a[y].c[0]=merge(x,a[y].c[0]);
        update(y);
        return y;
    }
}

void add(int x,int y,int z){
    D t2=split(rt,y);
    D t1=split(t2.c[0],x-1);
    totag(t1.c[1],z);
    rt=merge(merge(t1.c[0],t1.c[1]),t2.c[1]);
}

void ins(int x,int z){
    D tt=split(rt,x);
    rt=merge(merge(tt.c[0],z),tt.c[1]);
}

void del(int x){
    D t2=split(rt,x);
    D t1=split(t2.c[0],x-1);
    rt=merge(t1.c[0],t2.c[1]);
}

void get(int x,int y){
    D t2=split(rt,y);
    D t1=split(t2.c[0],x-1);
    printf("%d\n",a[t1.c[1]].mn);
    rt=merge(merge(t1.c[0],t1.c[1]),t2.c[1]);
}

void reverse(int x,int y){
    D t2=split(rt,y);
    D t1=split(t2.c[0],x-1);
    a[t1.c[1]].rev^=1;
    rt=merge(merge(t1.c[0],t1.c[1]),t2.c[1]);
}

void revolve(int x,int y,int z){
    D t2=split(rt,y);
    D t1=split(t2.c[0],x-1);
    D tt=split(t1.c[1],z);
    rt=merge(merge(merge(t1.c[0],tt.c[1]),tt.c[0]),t2.c[1]);
}

int main(){
    int i,x,y,z;
    char s[9];
    n=rd();
    for(i=1;i<=n;i++) a[i].input();
    rt=build(1,n);
    m=rd();
    for(i=1;i<=m;i++){
        scanf("%s",s);
        if(s[0]=='A'){
            x=rd(),y=rd(),z=rd();
            add(x,y,z);
        }
        else if(s[0]=='I'){
            x=rd();
            a[++n].input();
            ins(x,n);
        }
        else if(s[0]=='D'){
            x=rd();
            del(x);
        }
        else if(s[0]=='M'){
            x=rd(),y=rd();
            get(x,y);
        }
        else if(s[3]=='E'){
            x=rd(),y=rd();
            reverse(x,y);
        }
        else{
            x=rd(),y=rd(),z=rd();
            z=(z%(y-x+1)+(y-x+1))%(y-x+1);
            z=(y-x+1)-z;
            revolve(x,y,z);
        }
    }
    return 0;
}

非旋treap模板的更多相关文章

  1. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

  2. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  3. 非旋 treap 结构体数组版(无指针)详解,有图有真相

    非旋  $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ  ...

  4. 2018.08.27 rollcall(非旋treap)

    描述 初始有一个空集,依次插入N个数Ai.有M次询问Bj,表示询问第Bj个数加入集合后的排名为j的数是多少 输入 第一行是两个整数N,M 接下来一行有N个整数,Ai 接下来一行有M个整数Bj,保证数据 ...

  5. 非旋Treap总结 : 快过Splay 好用过传统Treap

    非旋$Treap$ 其高级名字叫$Fhq\ Treap$,既然叫$Treap$,它一定满足了$Treap$的性质(虽然可能来看这篇的人一定知道$Treap$,但我还是多说几句:$Fhp\ Treap$ ...

  6. 2827: 千山鸟飞绝 非旋treap

    国际惯例的题面:看起来很不可做的样子,我们先来整理一下题意吧.就是,维护每个点曾经拥有过的最大的两个属性值,支持把点的位置移动.我们用map对每个位置进行离散化,对每个位置建立一个平衡树.为了方便分离 ...

  7. 2081.09.22 Kuma(非旋treap)

    描述 有N张卡片,编号从0到n-1, 刚开始从0到n-1按顺序排好. 现有一个操作, 对于p. l,表示从第p张卡片之后的l张卡片拿到 最前面. 例如n=7的时候, 刚开始卡片序列为0 1 2 3 4 ...

  8. 2018.08.06 bzoj1500: [NOI2005]维修数列(非旋treap)

    传送门 平衡树好题. 我仍然是用的fhqtreap,感觉速度还行. 维护也比线段树splay什么的写起来简单. %%%非旋treap大法好. 代码: #include<bits/stdc++.h ...

  9. 2018.08.05 bzoj3223: Tyvj 1729 文艺平衡树(非旋treap)

    传送门 经典的平衡树问题,之前已经用splay写过一次了,今天我突发奇想,写了一发非旋treap的版本,发现挺好写的(虽然跑不过splay). 代码: #include<bits/stdc++. ...

随机推荐

  1. 8 HTML&JS等前端知识系列之jquery的自定义方法

    preface 有时候我们在前端写jquery的时候,会自己自定义些方法,这样可以不需要重复造轮子.先说说2种自定义方法的区别: 不跟在选择器后面的 跟在选择器后面的. 那下面说说如何自定义jquer ...

  2. oracle--游标--bai

    --复制表 create table emp as(select * from scott.emp); select * from emp; --(1) 最简单的游标 declare --声明并初始化 ...

  3. Win10 磁盘占用 100% 有效解决办法

    立即查看 任务管理器,看看是不是有一个 服务主机 unistack服务组或者找类似名称的,点开以后你会看到里面有同步主机 blablah请你毫不犹豫的结束它!结束它!结束它! 按下WIN+R调出运行, ...

  4. 抓取百万知乎用户信息之HttpHelper的迭代之路

    什么是Httphelper? httpelpers是一个封装好拿来获取网络上资源的工具类.因为是用http协议,故取名httphelper. httphelper出现的背景 使用WebClient可以 ...

  5. Yii ActiveRecord 的via和viaTable示例

    Yii中,将两个不相关的表利用中间表关联有via和viaTable两种方法,这里通过用户权限查询来进行示例. 关系如上,需要建立三个表 用户表 权限表 用户表 数据: 权限表 数据: 关联表 数据: ...

  6. 关于JQ toggle 的注意事项

    1.9.1以后的版本,好像不支持 jq 的 toggle function的用法啦.

  7. TCP/IP 协议中的滑动窗口

    一个例子明白发送缓冲区.接受缓冲区.滑动窗口协议之间的关系. 在上面的几篇文章中简单介绍了上述几个概念在TCP网络编程中的关系,也对应了几个基本socket系统调用的几个行为,这里再列举一个例子,由于 ...

  8. 生产环境中,数据库升级维护的最佳解决方案flyway

    官网:https://flywaydb.org/ 转载:http://casheen.iteye.com/blog/1749916 1.  引言 想到要管理数据库的版本,是在实际产品中遇到问题后想到的 ...

  9. [ActiveMQ]初识ActiveMQ

    初识ActiveMQ ActiveMQ介绍 官方网站:http://activemq.apache.org/ 最新版本:ActiveMQ 5.14.1(2016-10-28) 最新版本下载链接:htt ...

  10. angularJS实践过程中出现的问题总结

    同名服务 在一次项目里,之前是同事写的.我有一次在异步获取服务器上的数据时,习惯把api地址写在一个服务Store里,但是程序总是返回Store.api.get()里的get is undefined ...