zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Java学习二十九天
    Java学习二十八天
    47. Permutations II 全排列可重复版本
    46. Permutations 全排列,无重复
    subset ii 子集 有重复元素
    339. Nested List Weight Sum 339.嵌套列表权重总和
    251. Flatten 2D Vector 平铺二维矩阵
    217. Contains Duplicate数组重复元素
    209. Minimum Size Subarray Sum 结果大于等于目标的最小长度数组
    438. Find All Anagrams in a String 查找字符串中的所有Anagrams
  • 原文地址:https://www.cnblogs.com/AKMer/p/9987089.html
Copyright © 2011-2022 走看看