• spoj 4487. Can you answer these queries VI (gss6) splay 常数优化


    4487. Can you answer these queries VI

    Problem code: GSS6



     

    Given a sequence A of N (N <= 100000) integers, you have to apply Q (Q <= 100000) operations:

    Insert, delete, replace an element, find the maximum contiguous(non empty) sum in a given interval.

    Input

    The first line of the input contains an integer N.
    The following line contains N integers, representing the starting
    sequence A1..AN, (|Ai| <= 10000).

    The third line contains an integer Q. The next Q lines contains the operations in following form:

    I x y: insert element y at position x (between x - 1 and x).
    D x  : delete the element at position x.
    R x y: replace element at position x with y.
    Q x y: print max{Ai + Ai+1 + .. + Aj | x <= i <= j <= y}.

    All given positions are valid, and given values are between -10000 and +10000.

    The sequence will never be empty.

    Output

    For each "Q" operation, print an integer(one per line) as described above.

    Example

    Input:
    5
    3 -4 3 -1 6
    10
    I 6 2
    Q 3 5
    R 5 -4
    Q 3 5
    D 2
    Q 1 5
    I 2 -10
    Q 1 6
    R 2 -1
    Q 1 6

    Output:
    8
    3
    6
    3
    5


      第二次写splay居然遇上了考splay的常数优化。弄了很久。首先是读入优化,貌似SPOJ上面数据有' '所以要特殊判断。然后inline所有函数,最后把splay移到一个struct里面会加速很多。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<string>
    #include<queue>
    using namespace std;
    #ifdef WIN32
    #define LL "%I64d"
    #else
    #define LL "%lld"
    #endif
    #define MAXN 110000
    #define MAXV MAXN*2
    #define MAXE MAXV*2
    #define MAXT MAXN*2
    #define INF 0x3f3f3f3f
    #define INFL 0x3f3f3f3f3f3f3f3fLL
    #define lch splay[now].ch[0]
    #define rch splay[now].ch[1]
    typedef long long qword;
    inline int nextInt()
    {
            char ch;
            int x=0;
            bool flag=false;
            do
                    ch=(char)getchar(),flag=(ch=='-')?true:flag;
            while(ch<'0'||ch>'9');
            do x=x*10+ch-'0';
            while (ch=(char)getchar(),ch<='9' && ch>='0');
            return x*(flag?-1:1);
    }
    
    int n,m;
    int root=0,topt=0;;
    struct sss
    {
            int lx,rx,mx,val,sum,siz,pnt;
            int ch[2];
    }splay[MAXT];
    inline void up(int now)
    {
            splay[now].lx=splay[now].rx=splay[now].mx=-INF;
            if (lch)splay[now].lx=max(splay[now].lx,splay[lch].lx);
            splay[now].lx=max(splay[now].lx,max(splay[lch].sum+splay[now].val,splay[lch].sum+splay[now].val+splay[rch].lx));
            
            if (rch)splay[now].rx=max(splay[now].rx,splay[rch].rx);
            splay[now].rx=max(splay[now].rx,max(splay[rch].sum+splay[now].val,splay[rch].sum+splay[now].val+splay[lch].rx));
    
            splay[now].mx=splay[now].val;
            if (lch)splay[now].mx=max(splay[now].mx,splay[lch].mx);
            if (rch)splay[now].mx=max(splay[now].mx,splay[rch].mx);
            splay[now].mx=max(splay[now].mx,splay[lch].rx+splay[rch].lx+splay[now].val);
            splay[now].mx=max(splay[now].mx,splay[rch].lx+splay[now].val);
            splay[now].mx=max(splay[now].mx,splay[lch].rx+splay[now].val);
    
            splay[now].siz=splay[lch].siz+splay[rch].siz+1;
            splay[now].sum=splay[lch].sum+splay[rch].sum+splay[now].val;
    }
    
    inline void Rotate(int now)
    {
            int p=splay[now].pnt,anc=splay[p].pnt;
            int dir=splay[p].ch[0]==now;
            if (anc)
                    splay[anc].ch[splay[anc].ch[1]==p]=now;
            splay[now].pnt=anc;
    
            splay[splay[now].ch[dir]].pnt=p;
            splay[p].ch[1-dir]=splay[now].ch[dir];
    
            splay[p].pnt=now;
            splay[now].ch[dir]=p;
            up(p);
            up(now);
    }
    /*
    inline int Get_kth(int now,int rk)
    {
            if (rk==siz[splay[now].ch[0]]+1)
                    return now;
            if (rk<siz[splay[now].ch[0]]+1)
                    return Get_kth(splay[now].ch[0],rk);
            else 
                    return Get_kth(splay[now].ch[1],rk-siz[splay[now].ch[0]]-1);
    }*/
    inline int Get_kth(int rk)
    {
            int now=root;
            while (rk!=splay[splay[now].ch[0]].siz+1)
            {
                    if (rk>splay[splay[now].ch[0]].siz+1)
                    {
                            rk-=splay[splay[now].ch[0]].siz+1;
                            now=splay[now].ch[1];
                    }else 
                    {
                            now=splay[now].ch[0];
                    }
            }
            return now;
    }
    
    inline void Splay(int now,int tp=0)
    {
            if (now==tp)return ;
            while (splay[now].pnt!=tp)
            {
                    int p=splay[now].pnt,anc=splay[p].pnt;
                    if (anc==tp)
                            Rotate(now);
                    else if( (splay[anc].ch[0]==p) == (splay[p].ch[0]==now))
                    {
                            Rotate(p);
                            Rotate(now);
                    }else
                    {
                            Rotate(now);
                            Rotate(now);
                    }
            }
            if (tp==0)root=now;
    }
    inline void Insert(int pos,int v)
    {
            int now=++topt;
            splay[now].ch[0]=splay[now].ch[1]=0;
            splay[now].pnt=0;
            splay[now].val=v;
            splay[now].siz=1;
            splay[now].lx=splay[now].rx=splay[now].mx=splay[now].sum=v;
            if (!pos)
            {
                    Splay(Get_kth(1));
                    splay[now].ch[1]=root;
                    splay[root].pnt=now;
                    root=now;
                    up(now);
                    return ;
            }
            Splay(Get_kth(pos));
            splay[now].pnt=root;
            splay[now].ch[1]=splay[root].ch[1];
            splay[splay[root].ch[1]].pnt=now;
            splay[root].ch[1]=now;
            up(now);
            up(root);
            return ;
    }
    inline void Delete(int pos)
    {
            Splay(Get_kth(pos));
            if (pos!=splay[root].siz)
            {
                    Splay(Get_kth(pos+1),root);/**/
                    splay[splay[root].ch[1]].ch[0]=splay[root].ch[0];
                    splay[splay[root].ch[0]].pnt=splay[root].ch[1];;
                    splay[splay[root].ch[1]].pnt=splay[root].pnt;
                    root=splay[root].ch[1];
            }else
            {
                    root=splay[root].ch[0];
                    splay[root].pnt=0;
            }
            up(root);
    }
    inline int Qry_mxs(int l,int r)
    {
            if (l==1 && r==splay[root].siz)
            {
                    return splay[root].mx;
            }else if (l==1)
            {
                    Splay(Get_kth(r+1));
                    return splay[splay[root].ch[0]].mx;
            }else if (r==splay[root].siz)
            {
                    Splay(Get_kth(l-1));
                    return splay[splay[root].ch[1]].mx;
            }else
            {
                    Splay(Get_kth(l-1));
                    Splay(Get_kth(r+1),root);
                    return splay[splay[splay[root].ch[1]].ch[0]].mx;
            }
    }
    inline void Chg_val(int pos,int v)
    {
            Splay(Get_kth(pos));
            splay[root].val=v;
            up(root);
    }
    void Scan(int now)
    {
            if (!now)return ;
            if (splay[now].siz!=splay[lch].siz+splay[rch].siz+1)throw 2;
            if (splay[now].ch[0])
            {
                    if (splay[splay[now].ch[0]].pnt!=now)throw 1;
                    Scan(splay[now].ch[0]);
            }
            printf("%d ",splay[now].val);
            if (splay[now].ch[1])
            {
                    if (splay[splay[now].ch[1]].pnt!=now)throw 1;
                    Scan(splay[now].ch[1]);
            }
    }
    void Build_tree(int &now,int *num,int l,int r)
    {
            now=++topt;
            int mid=(l+r)>>1;
            splay[now].siz=1;
            splay[now].sum=splay[now].val=splay[now].mx=splay[now].lx=splay[now].rx=num[mid];
            if (l<=mid-1)Build_tree(lch,num,l,mid-1);
            if (mid+1<=r)Build_tree(rch,num,mid+1,r);
            splay[lch].pnt=now;
            splay[rch].pnt=now;
            up(now);
    }
    int num[MAXN];
    int main()
    {
            freopen("input.txt","r",stdin);
            //freopen("output.txt","w",stdout);
            int i,j,k;
            int x,y,z;
            scanf("%d",&n);
            for (i=0;i<n;i++)
            {
                    x=nextInt();
                    num[i]=x;
            }
            Build_tree(root,num,0,n-1);
            scanf("%d
    ",&m);
            char opt;
            for (i=0;i<m;i++)
            {
                    opt=getchar();
                    //scanf("%c",&opt);
                    if (opt=='I')
                    {
                        //    scanf("%d%d",&x,&y);
                            x=nextInt();y=nextInt();
                            x--;
                            Insert(x,y);
                    }else if (opt=='Q')
                    {
                        //    scanf("%d%d",&x,&y);
                            x=nextInt();y=nextInt();
                            printf("%d
    ",Qry_mxs(x,y));
                    }else if (opt=='R')
                    {
                        //    scanf("%d%d",&x,&y);
                            x=nextInt();y=nextInt();
                            Chg_val(x,y);
                    }else if (opt=='D')
                    {
                        //    scanf("%d",&x);
                            x=nextInt();
                            Delete(x);
                    }
                    getchar();
            }
            return 0;
    }
    
    
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    Vuex2.0+Vue2.0构建备忘录应用实践
    一步步构造自己的vue2.0+webpack环境
    .NET入行之工作前
    webpack入门之简单例子跑起来
    vue中,class、内联style绑定、computed属性
    wap问答系统工作总结
    ASP.NET Core Api网关Ocelot的中文文档
    在pom.xml中添加Spring依赖
    【java基础】从反射开始(Reflection)
    【java基础】 == 和 equals() 的区别
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4029533.html
Copyright © 2020-2023  润新知