首页 > 代码库 > spoj 4487. Can you answer these queries VI splay 常数优化

spoj 4487. Can you answer these queries VI 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上面数据有‘\r‘所以要特殊判断。然后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\n",&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\n",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;}

 

spoj 4487. Can you answer these queries VI splay 常数优化