Luogu P2042 [NOI2005]列の数を維持します

タイトル説明

)実際の入力ファイル・スペースを表し、次の6つの動作をサポートしています:(「_」バーをフォーマットすること下線を注意してください、列数のメンテナンスを必要と手順を記述してください。

入出力フォーマット

入力フォーマット:
入力ファイルの最初の行は、2点の数NおよびMが含まれ、Nは、Mが実行される操作の数を表し、列の最初の数の数を表します。2行目はNデジタル、初期の説明では、列の数が含まれています。次のM行、各コマンドの形で問題の形式の説明を参照

出力フォーマット:
GET-SUMとMAX-SUM操作の入力データは、シーケンス内の出力ファイルに行ごとに各回答(番号)の結果を印刷します。

サンプル入力と出力

入力サンプル#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

出力サンプル#1:

-1

10

1

10

説明

あなたは、任意の時点で、少なくとも1個の列数を考えることができます。

入力データが正確でなければならない、即ち、数字の特定の一連の存在下で数指定された場所。

列の数を含む30,000までの任意の時点でのデータの50%。

データの100%が、時間の任意の数は、列の数は500,000までを有します。

データの100%、[-1000 1000]内の列の数の両方における任意の瞬間の数のいずれか。

データの100%、M≤20000は、桁の総数は4,000,000を挿入超えません。

分析

プログラミング17を考えて複雑

この質問に考えることは非常に簡単です、第1の平衡ツリーの使用を決定し、その後、LSは、RSは、各機能の完了後に1つずつ、最大かつを維持します。ノードを再利用する必要があることに注意してください。全体的な複雑性O(n)を回収します。O(nlogn)の全体的な複雑。

コード

#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;
}

おすすめ

転載: www.cnblogs.com/Algebra-hy/p/11031141.html