zoukankan      html  css  js  c++  java
  • 及其简短的Splay代码

    #include <stdio.h>
    #include <queue>
    #include <algorithm>
    #include <stdlib.h>
    #include <math.h>
    #include <iostream>
    #define inf 1000000000
    using namespace std;
    #define getch() getchar()
    inline int F() {register int aa , bb , ch;
        while(ch = getch() , (ch<'0'||ch>'9') && ch != '-'); ch == '-' ? aa=bb=0 : (aa=ch-'0',bb=1);
        while(ch = getch() , ch>='0'&&ch<='9') aa = aa*10 + ch-'0'; return bb ? aa : -aa;
    }
    const int Maxn = 1000005;
    queue<int> q;
    int n , m , root , sz;
    int fa[Maxn] , c[Maxn][2] , mx[Maxn] , lx[Maxn] , rx[Maxn] , v[Maxn] , size[Maxn] , sum[Maxn] , a[Maxn] , id[Maxn];
    bool lazy[Maxn] , rev[Maxn];
     
    void update(int x) {
        int lc = c[x][0] , rc = c[x][1];
        sum[x] = sum[lc] + sum[rc] + v[x];
        size[x] = size[lc] + size[rc] + 1;
        mx[x] = max(mx[lc] , mx[rc]);
        mx[x] = max(mx[x] , rx[lc]+v[x]+lx[rc]);
        lx[x] = max(lx[lc] , sum[lc] + v[x] + lx[rc]);
        rx[x] = max(rx[rc] , sum[rc] + v[x] + rx[lc]);
    }
     
    void downpush(int x) {
        int lc = c[x][0] , rc = c[x][1];
        if(lazy[x]) {
            rev[x] = lazy[x] = 0;
            if(lc) lazy[lc] = 1 , v[lc] = v[x] , sum[lc] = v[x]*size[lc];
            if(rc) lazy[rc] = 1 , v[rc] = v[x] , sum[rc] = v[x]*size[rc];
            if(v[x] >= 0) {
                if(lc) lx[lc] = rx[lc] = mx[lc] = sum[lc];
                if(rc) lx[rc] = rx[rc] = mx[rc] = sum[rc];
            }
            else {
                if(lc) lx[lc] = rx[lc] = 0 , mx[lc] = v[x];
                if(rc) lx[rc] = rx[rc] = 0 , mx[rc] = v[x];
            }
        }
        if(rev[x]) {
            rev[x] = 0;
            rev[lc] ^= 1;
            rev[rc] ^= 1;
            swap(lx[lc] , rx[lc]);
            swap(lx[rc] , rx[rc]);
            c[x][0] = rc;
            c[x][1] = lc;
            swap(lx[x] , rx[x]);
        }
    }
     
    void rotate(int&root , int x) {
        int y = fa[x] , z = fa[y] , p , q;
        if(x == c[y][0]) p = 0; else p = 1;
        q = p^1;
        if(y == root) root = x;
        else {
            if(c[z][0] == y) c[z][0] = x;
            else c[z][1] = x;
        }
        fa[x] = z; fa[y] = x; fa[c[x][q]] = y;
        c[y][p] = c[x][q]; c[x][q] = y;
        update(y); update(x);
    }
    void splay(int&root , int x) {
        int y , z;
        while(x != root) {
            y = fa[x] , z = fa[y];
            if(y != root) {
                if((x == c[y][0]) ^ (y == c[z][0])) rotate(root , x);
                else rotate(root , y);
            }
            rotate(root , x);
        }
    }
     
    int find(int x , int rk) {
        downpush(x);
        int lc = c[x][0] , rc = c[x][1];
        if(size[lc] + 1 == rk) return x;
        if(size[lc] >= rk) return find(lc , rk);
        else return find(rc , rk-size[lc]-1);
    }
     
    void rec(int x) {
        if(!x) return ;
        int lc = c[x][0] , rc = c[x][1];
        rec(lc);rec(rc);q.push(x);
        fa[x] = c[x][0] = c[x][1] = lazy[x] = rev[x] = 0;
    }
     
    int split(int k , int tot) {
        int x = find(root , k);
        splay(root , x);
        x = find(root , k+tot+1);
        splay(c[root][1] , x);
        return c[ c[root][1] ][0];
    }
     
    void query(int k , int tot) {
        int x = split(k , tot);
        printf("%d
    ",sum[x]);
    }
     
    void modify(int k , int tot , int val) {
        int x = split(k , tot) , y = fa[x];
        v[x] = val; lazy[x] = 1; sum[x] = size[x]*val;
        if(val >= 0) lx[x] = rx[x] = mx[x] = sum[x];
        else lx[x] = rx[x] = 0 , mx[x] = val;
        update(y); update(fa[y]);
    }
     
    void reverse(int k , int tot) {
        int x = split(k , tot);
        if(!lazy[x]) {
            rev[x] ^= 1;
            downpush(x);
            update(fa[x]);
            update(fa[fa[x]]);
        }
    }
     
    void erase(int k , int tot) {
        int x = split(k , tot) , y = fa[x];
        rec(x); c[y][0] = 0;
        update(y); update(fa[y]);
    }
    void build(int l,int r,int f)
    {
        if(l>r)return;
        int mid=(l+r)>>1,now=id[mid],last=id[f];
        if(l==r)
        {
            sum[now]=a[l];size[now]=1;
            lazy[now]=rev[now]=0;
            if(a[l]>=0)lx[now]=rx[now]=mx[now]=a[l];
            else lx[now]=rx[now]=0,mx[now]=a[l];
        }
        else build(l,mid-1,mid),build(mid+1,r,mid);
        v[now]=a[mid];fa[now]=last;update(now);
        c[last][mid>=f]=now;
       }
    void insert(int k,int tot)
    {
        for(int i=1;i<=tot;i++)a[i]=F();
        for(int i=1;i<=tot;i++)
            if(!q.empty())id[i]=q.front(),q.pop();
            else id[i]=++sz;
        build(1,tot,0);int z=id[(1+tot)>>1];
        int x=find(root,k+1),y=find(root,k+2);
        splay(root,x);splay(c[x][1],y);
        fa[z]=y;c[y][0]=z;
        update(y);update(x);
    }
     
    int main() {
        n = F(); m = F();
        mx[0] = a[1] = a[n+2] = -inf;
        for(int i=1; i<=n; ++i) {
            a[i+1] = F();
        }
        for(int i=1;i<=n+2;i++)id[i]=i;
        build(1,n+2,0);
        root = (n+3) >> 1;sz = n + 2;
        int k , tot , val;
        char ch[10];
        while(m--) {
            scanf("%s",ch);
            if(ch[0]!='M' || ch[2] != 'X') k = F() , tot = F();
            if(ch[0] == 'I') insert(k , tot);
            if(ch[0] == 'D') erase(k , tot);
            if(ch[0] == 'M') {
                if(ch[2] == 'X') printf("%d
    ",mx[root]);
                else val = F() , modify(k , tot , val);
            }
            if(ch[0] == 'R') reverse(k , tot);
            if(ch[0] == 'G') query(k , tot);
        }
    }

    Splay的核心操作

    void rotate(int&root , int x) {
        int y = fa[x] , z = fa[y] , p , q;
        if(x == c[y][0]) p = 0; else p = 1;
        q = p^1;
        if(y == root) root = x;
        else {
            if(c[z][0] == y) c[z][0] = x;
            else c[z][1] = x;
        }
        fa[x] = z; fa[y] = x; fa[c[x][q]] = y;
        c[y][p] = c[x][q]; c[x][q] = y;
        update(y); update(x);
    }
    void splay(int&root , int x) {
        int y , z;
        while(x != root) {
            y = fa[x] , z = fa[y];
            if(y != root) {
                if((x == c[y][0]) ^ (y == c[z][0])) rotate(root , x);
                else rotate(root , y);
            }
            rotate(root , x);
        }
    }
  • 相关阅读:
    解决依赖的moduleBuildConfig.DEBUG总是未false的问题
    android异步处理机制
    Android 5.0 行为变更
    Android 6.0 变更
    Android 7.0 行为变更
    android 8.0变更
    Android 4.4 API
    Android常见问题集锦
    Android笔记汇总目录
    Delphi中Indy 10的安装和老版本的卸载
  • 原文地址:https://www.cnblogs.com/linkzijun/p/6172110.html
Copyright © 2011-2022 走看看