• BZOJ1252:序列终结者


    浅谈(splay)https://www.cnblogs.com/AKMer/p/9979592.html

    浅谈(fhq)_(treap)https://www.cnblogs.com/AKMer/p/9981274.html

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1251

    平衡树区间操作模板题。

    时间复杂度:(O(mlogn))

    空间复杂度:(O(n))

    (splay)版代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=5e4+5;
    
    int n,m;
    
    int read() {
        int x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    struct Splay {
        int tot,root;
        bool rev[maxn];
        int son[maxn][2];
        int val[maxn],mx[maxn];
        int fa[maxn],siz[maxn],add[maxn];
    
        void update(int p) {
            siz[p]=siz[son[p][0]]+1+siz[son[p][1]];
            mx[p]=max(mx[son[p][0]],max(val[p],mx[son[p][1]]));
        }
        
        void build(int l,int r,int lst) {
            if(r<l)return;
            if(l==r) {
                siz[l]=1;fa[l]=lst;
                son[lst][l>lst]=l;
                return;
            }
            int mid=(l+r)>>1;
            fa[mid]=lst;son[lst][mid>lst]=mid;
            build(l,mid-1,mid);build(mid+1,r,mid);
            update(mid);
        }
    
        void prepare() {
            tot=n+2;build(1,tot,0);root=(n+3)>>1;mx[0]=-2e9;
        }
    
        void make_add_tag(int p,int v) {
            val[p]+=v;mx[p]+=v;add[p]+=v;
        }
    
        void make_rev_tag(int p) {
            rev[p]^=1;swap(son[p][0],son[p][1]);
        }
    
        void push_down(int p) {
            if(add[p]) {
                if(son[p][0])make_add_tag(son[p][0],add[p]);
                if(son[p][1])make_add_tag(son[p][1],add[p]);
                add[p]=0;
            }
            if(rev[p]) {
                make_rev_tag(son[p][0]);
                make_rev_tag(son[p][1]);
                rev[p]=0;
            }
        }
    
        int find(int u,int rk) {
            push_down(u);
            if(siz[son[u][0]]+1==rk)return u;
            if(siz[son[u][0]]>=rk)return find(son[u][0],rk);
            return find(son[u][1],rk-siz[son[u][0]]-1);
        }
    
        int t(int u) {
            return son[fa[u]][1]==u;
        }
    
        void rotate(int u) {
            int ret=t(u),f=fa[u],s=son[u][ret^1];
            son[f][ret]=s;if(s)fa[s]=f;son[u][ret^1]=f;
            fa[u]=fa[f];if(fa[f])son[fa[f]][t(f)]=u;
            fa[f]=u;update(f);update(u);
        }
    
        void splay(int goal,int u) {
            int tmp=fa[goal];
            while(fa[u]!=tmp) {
                if(fa[fa[u]]!=tmp) {
                    if(t(fa[u])==t(u))rotate(fa[u]);
                    else rotate(u);
                }
                rotate(u);
            }
            if(!tmp)root=u;
        }
    
        void ADD(int l,int r,int v) {
            int u1=find(root,l-1),u2=find(root,r+1);
            splay(root,u1);splay(son[root][1],u2);
            make_add_tag(son[u2][0],v);
        }
    
        void rever(int l,int r) {
            int u1=find(root,l-1),u2=find(root,r+1);
            splay(root,u1);splay(son[root][1],u2);
            make_rev_tag(son[u2][0]);
        }
    
        int find_mx(int l,int r) {
            int u1=find(root,l-1),u2=find(root,r+1);
            splay(root,u1);splay(son[root][1],u2);
            return mx[son[u2][0]];
        }
    }T;
    
    int main() {
        n=read(),m=read();
        T.prepare();
        for(int i=1;i<=m;i++) {
            int opt=read(),l=read()+1,r=read()+1;
            if(opt==1) {
                int v=read();
                T.ADD(l,r,v);
            }
            if(opt==2)T.rever(l,r);
            if(opt==3)printf("%d
    ",T.find_mx(l,r));
        }
        return 0;
    }
    

    (fhq)_(treap)版代码如下:

    #include <ctime>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef pair<int,int> pii;
    
    const int maxn=5e4+5;
    
    int n,m;
    
    int read() {
        int x=0,f=1;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
        for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
        return x*f;
    }
    
    struct fhq_treap {
        int tot,root;
        bool rev[maxn];
        int son[maxn][2];
        int mx[maxn],siz[maxn];
        int val[maxn],add[maxn],fix[maxn];
    
        void update(int p) {
            siz[p]=siz[son[p][0]]+1+siz[son[p][1]];
            mx[p]=max(mx[son[p][0]],max(val[p],mx[son[p][1]]));
        }
    
        void build(int l,int r,int lst) {
            if(r<l)return;
            if(l==r) {
                siz[l]=1;son[lst][l>lst]=l;
                fix[l]=rand();return;
            }
            int mid=(l+r)>>1;
            son[lst][mid>lst]=mid;fix[mid]=rand();
            build(l,mid-1,mid);build(mid+1,r,mid);
            update(mid);
        }
        
        void prepare() {
            tot=n;root=(1+n)>>1;build(1,n,0);mx[0]=-2e9;
        }
    
        void make_add_tag(int p,int v) {
            mx[p]+=v;val[p]+=v;add[p]+=v;
        }
    
        void make_rev_tag(int p) {
            rev[p]^=1;swap(son[p][0],son[p][1]);
        }
    
        void push_down(int p) {
            if(add[p]) {
                if(son[p][0])make_add_tag(son[p][0],add[p]);
                if(son[p][1])make_add_tag(son[p][1],add[p]);
                add[p]=0;
            }
            if(rev[p]) {
                make_rev_tag(son[p][0]);
                make_rev_tag(son[p][1]);
                rev[p]=0;
            }
        }
    
        pii split(int u,int rk) {
            if(!rk)return make_pair(0,u);
            if(rk==siz[u])return make_pair(u,0);
            push_down(u);
            if(siz[son[u][0]]>=rk) {
                pii tmp=split(son[u][0],rk);
                son[u][0]=tmp.second;update(u);
                return make_pair(tmp.first,u);
            }
            else {
                pii tmp=split(son[u][1],rk-siz[son[u][0]]-1);
                son[u][1]=tmp.first;update(u);
                return make_pair(u,tmp.second);
            }
        }
    
        int merge(int a,int b) {
            if(!a||!b)return a+b;
            push_down(a);push_down(b);
            if(fix[a]>fix[b])return son[a][1]=merge(son[a][1],b),update(a),a;
            else return son[b][0]=merge(a,son[b][0]),update(b),b;
        }
    
        void ADD(int l,int r,int v) {
            pii tmp1=split(root,r);
            pii tmp2=split(tmp1.first,l-1);
            make_add_tag(tmp2.second,v);
            root=merge(merge(tmp2.first,tmp2.second),tmp1.second);
        }
    
        void rever(int l,int r) {
            pii tmp1=split(root,r);
            pii tmp2=split(tmp1.first,l-1);
            make_rev_tag(tmp2.second);
            root=merge(merge(tmp2.first,tmp2.second),tmp1.second);
        }
    
        int find_mx(int l,int r) {
            pii tmp1=split(root,r);
            pii tmp2=split(tmp1.first,l-1);
            int res=mx[tmp2.second];
            root=merge(merge(tmp2.first,tmp2.second),tmp1.second);
            return res;
        }
    }T;
    
    int main() {
        srand(time(0));
        n=read(),m=read();
        T.prepare();
        for(int i=1;i<=m;i++) {
            int opt=read(),l=read(),r=read();
            if(opt==1) {
                int v=read();
                T.ADD(l,r,v);
            }
            if(opt==2)T.rever(l,r);
            if(opt==3)printf("%d
    ",T.find_mx(l,r));
        }
        return 0;
    }
    
  • 相关阅读:
    Linux基础知识[1]【ACL权限】
    docker 入门学习篇【基本命令与操作】
    centos7.1下 Docker环境搭建
    RHEL6.5下更新python至2.7版本
    Github初学者探索
    vmware下linux虚拟机传文件解决方案之 xftp
    mysql 常用操作命令
    常用DNS记录
    常见网络协议端口号整理
    DNS原理及其解析过程 精彩剖析
  • 原文地址:https://www.cnblogs.com/AKMer/p/9987089.html
Copyright © 2020-2023  润新知