Luogu P2042 [NOI2005] to maintain the number of columns

Title Description

Please write a procedure that requires the maintenance of a number of columns, supports the following six operating :( Please note that underline formatting bar '_' represents the actual input file space)

Input and output formats

Input format:
first line of the input file contains two numbers N and M, N represents the number of the initial number of columns, M represents the number of operations to be performed. Line 2 contains N digital, the number of columns at the initial description. The following M lines, each one command, see the format description of the problem in the form

Output format:
input data of GET-SUM and MAX-SUM operations, print the results to the output file in sequence, each answer (number) per line.

Sample input and output

Input Sample # 1:

9 8

2 -6 3 5 1 -5 -3 6 3

GET-SUM 5 4

MAX-SUM

INSERT 8 3 -5 7 2

DELETE 12 1

MAKE-SAME 3 3 2

REVERSE 3 6

GET-SUM 5 4

MAX-SUM

Output Sample # 1:

-1

10

1

10

Explanation

You can think of at any time, the number of columns in at least 1 number.

The input data must be correct, i.e., the number specified location in the presence of a certain series of numbers.

50% of the data, at any time up to 30,000 containing the number of columns;

100% of the data, any number of time having up to 500,000 in number of columns.

100% of the data, any of a number at any moment in both the number of columns in the [-1000, 1000] within.

100% of the data, M ≤20 000, does not exceed the total number of digits inserted 4,000,000.

analysis

Complexity thinking programming 17

Thinking on this question is very simple, first determine the use of balanced tree, and then ls, rs maintain the largest and, one by one after the completion of each function. Note that the nodes need to be recycled. Recovering overall complexity O (n). The overall complexity of O (nlogn).

Code

#include <cstdio>
#include <cstdlib>
#define rt ch[0][0]
const int N=500000,S=N+100,inf=(1<<25)-1;
int n,m,a[S],bin[S],ch[S][2],ls[S],rs[S],fa[S],su[S],sz[S],mx[S],add[S],rev[S];
void rd(int &x)
{
    x=0;char c=getchar(),t=1;
    while (c!='-' && (c<'0' || c>'9')) c=getchar();
    if (c=='-') t=-1,c=getchar();
    while (c>='0' && c<='9') x=(x<<3)+(x<<1)+(c-'0'),c=getchar();
    x*=t;
}
void init()
{
    for (int i=0;i<=N;i++)
        bin[i]=i;
    bin[0]=1;

    rt=1;

    ls[0]=rs[0]=mx[0]=-inf;
    sz[0]=0;

    bin[0]=2;//use 1
    sz[1]=2;ch[1][1]=2;fa[1]=0;a[1]=-inf;add[1]=inf;

    bin[0]=3;//use 2
    sz[2]=1;fa[2]=1;add[2]=inf;a[2]=-inf;
}
inline int ma(int a,int b){if (a>b) return a;return b;}
inline int ma3(int a,int b,int c){return ma(a,ma(b,c));}
inline void swap(int &a,int &b){a^=b^=a^=b;}
inline void up(int x)
{
    int L=ch[x][0],R=ch[x][1];
    sz[x]=sz[L]+sz[R]+1;
    su[x]=su[L]+su[R]+a[x];
    ls[x]=ma3(ls[L],su[L]+a[x],su[L]+a[x]+ls[R]);
    rs[x]=ma3(rs[R],su[R]+a[x],su[R]+a[x]+rs[L]);
    int mid=ma(rs[L],0)+a[x]+ma(ls[R],0);
    mx[x]=ma3(mx[L],mx[R],mid);
    mx[x]=ma3(mx[x],ls[x],rs[x]);
}
inline void down(int x)
{
    int &L=ch[x][0],&R=ch[x][1];
    if (rev[x])
    {
        if (L)
        {
            rev[L]^=1;
            swap(ch[L][0],ch[L][1]);
            swap(ls[L],rs[L]);
        }
        if (R)
        {
            rev[R]^=1;
            swap(ch[R][0],ch[R][1]);
            swap(ls[R],rs[R]);
        }
        rev[x]=0;
    }
    if (add[x]!=inf)
    {
        if (L)
        {
            add[L]=add[x];
            su[L]=add[L]*sz[L];
            a[L]=add[L];
            if (add[x]>0)
                ls[L]=rs[L]=mx[L]=su[L];
            else
                ls[L]=rs[L]=mx[L]=a[L];
        }
        if (R)
        {
            add[R]=add[x];
            su[R]=add[R]*sz[R];
            a[R]=add[R];
            if (add[x]>0)
                ls[R]=rs[R]=mx[R]=su[R];
            else
                ls[R]=rs[R]=mx[R]=a[R];
        }
        add[x]=inf;
    }
}
inline bool lor(int x){return ch[fa[x]][1]==x;}
inline void link(int x,int fat,int o){fa[x]=fat;ch[fat][o]=x;}
inline void rotate(int x)
{
    int y=fa[x],r=fa[y];
    down(y);down(x);
    int rson=lor(y),yson=lor(x);
    link(ch[x][yson^1],y,yson);
    link(y,x,yson^1);
    link(x,r,rson);
    up(y);up(x);
}
void splay(int x,int to)
{
    to=fa[to];
    while (fa[x]!=to)
    {
        if (fa[fa[x]]==to) rotate(x);
        else if (lor(x)==lor(fa[x])) rotate(fa[x]),rotate(x);
        else rotate(x),rotate(x);
    }
}
void build(int &k,int fat,int l,int r)
{
    if (l>r)
    {
        k=0;
        return;
    }
    k=bin[bin[0]++];
    fa[k]=fat;
    int mid=(l+r)>>1;
    build(ch[k][0],k,l,mid-1);
    rd(a[k]);
    add[k]=inf;rev[k]=0;
    build(ch[k][1],k,mid+1,r);
    up(k);
}
void recycle(int k)
{
    if (!k) return;
    recycle(ch[k][0]);
    a[k]=su[k]=ls[k]=rs[k]=mx[k]=fa[k]=add[k]=rev[k]=0;
    bin[--bin[0]]=k;
    recycle(ch[k][1]);
    ch[k][0]=ch[k][1]=0;
}
int find(int x)
{
    int o=rt;
    while (o)
    {
        down(o);
        if (sz[ch[o][0]]+1==x)
            break;
        if (x<=sz[ch[o][0]])
            o=ch[o][0];
        else x-=sz[ch[o][0]]+1,o=ch[o][1];
    }
    return o;
}
void insert(int pos,int tot)
{
    pos++;
    int bg=find(pos),ed=find(pos+1);
    splay(bg,rt);
    splay(ed,ch[bg][1]);
    build(ch[ed][0],ed,1,tot);
    up(ed);up(bg);
}
void del(int pos,int tot)
{
    int bg=find(pos),ed=find(pos+tot+1);
    splay(bg,rt);splay(ed,ch[bg][1]);
    recycle(ch[ed][0]);
    ch[ed][0]=0;
    up(ed);up(bg);
}
void make_same(int pos,int tot,int x)
{
    int bg=find(pos),ed=find(pos+tot+1);
    splay(bg,rt);splay(ed,ch[bg][1]);
    int o=ch[ed][0];
    add[o]=x;su[o]=x*sz[o];a[o]=x;
    if (x>0) ls[o]=rs[o]=mx[o]=su[o];
    else ls[o]=rs[o]=mx[o]=a[o];
    up(ed);up(bg);
}
void reverse(int pos,int tot)
{
    int bg=find(pos),ed=find(pos+tot+1);
    splay(bg,rt);splay(ed,ch[bg][1]);
    down(bg);down(ed);
    int o=ch[ed][0];
    rev[o]=1;
    swap(ch[o][0],ch[o][1]);
    swap(ls[o],rs[o]);
    up(ed);up(bg);
}
void getsum(int pos,int tot)
{
    int bg=find(pos),ed=find(pos+tot+1);
    splay(bg,rt);
    splay(ed,ch[bg][1]);
    int o=ch[ed][0];
    printf("%d\n",su[o]);
}
int main()
{
    rd(n);rd(m);
    init();
    build(ch[2][0],2,1,n);up(2);up(1);
    char op[10];int tot,pos,x;
    while (m--)
    {
        scanf("%s",op);
        if (op[2]=='X')//max_sum
            printf("%d\n",mx[rt]);
        else
        {
            rd(pos);rd(tot);
            if (op[2]=='S')//Insert
                insert(pos,tot);
            else if (op[2]=='L')
                del(pos,tot);
            else if ('K'==op[2])
            {
                scanf("%d",&x);
                make_same(pos,tot,x);
            }
            else if ('V'==op[2])
                reverse(pos,tot);
            else getsum(pos,tot);
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Algebra-hy/p/11031141.html