码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ1500][NOI2005]维修数列

时间:2017-12-30 18:11:38      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:ota   ace   new   turn   pac   str   main   题目   algo   

BZOJ
Luogu
题目不放了

题解

这道题没有题解
仅此

code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 2e9
const int _ = 500050;
int n,m,fa[_],ls[_],rs[_],val[_],sigma[_],sz[_],rev[_],tag[_],pre[_],suf[_],sum[_],Stack[_],a[_],top,root;
char s[_];
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
void pushup(int x)
{
    sz[x]=sz[ls[x]]+sz[rs[x]]+1;
    sigma[x]=sigma[ls[x]]+sigma[rs[x]]+val[x];
    pre[x]=max(pre[ls[x]],sigma[ls[x]]+val[x]+pre[rs[x]]);
    suf[x]=max(suf[rs[x]],sigma[rs[x]]+val[x]+suf[ls[x]]);
    sum[x]=max(max(sum[ls[x]],sum[rs[x]]),suf[ls[x]]+val[x]+pre[rs[x]]);
}
void pushdown(int x)
{
    if (tag[x])
    {
        if (ls[x]) 
        {
            tag[ls[x]]=1,val[ls[x]]=val[x],sigma[ls[x]]=val[ls[x]]*sz[ls[x]];
            if (val[x]>=0) pre[ls[x]]=suf[ls[x]]=sum[ls[x]]=sigma[ls[x]];
            else pre[ls[x]]=suf[ls[x]]=0,sum[ls[x]]=val[ls[x]];
        }
        if (rs[x]) 
        {
            tag[rs[x]]=1,val[rs[x]]=val[x],sigma[rs[x]]=val[rs[x]]*sz[rs[x]];
            if (val[x]>=0) pre[rs[x]]=suf[rs[x]]=sum[rs[x]]=sigma[rs[x]];
            else pre[rs[x]]=suf[rs[x]]=0,sum[rs[x]]=val[rs[x]];
        }
        tag[x]=rev[x]=0;
    }
    if (rev[x]) 
    {
        swap(ls[ls[x]],rs[ls[x]]);
        swap(ls[rs[x]],rs[rs[x]]);
        swap(pre[ls[x]],suf[ls[x]]);
        swap(pre[rs[x]],suf[rs[x]]);
        if (ls[x]) rev[ls[x]]^=1;
        if (rs[x]) rev[rs[x]]^=1;
        rev[x]=0;
    }
}
void R_rotate(int x)
{
    int y=fa[x],z=fa[y];
    ls[y]=rs[x];
    if (rs[x]) fa[rs[x]]=y;
    fa[x]=z;
    if (z) if (y==ls[z]) ls[z]=x;else rs[z]=x;
    rs[x]=y;fa[y]=x;
    pushup(y);
}
void L_rotate(int x)
{
    int y=fa[x],z=fa[y];
    rs[y]=ls[x];
    if (ls[x]) fa[ls[x]]=y;
    fa[x]=z;
    if (z) if (y==ls[z]) ls[z]=x;else rs[z]=x;
    ls[x]=y;fa[y]=x;
    pushup(y);
}
void splay(int x,int goal)
{
    while (fa[x]!=goal)
    {
        int y=fa[x],z=fa[y];
        if (z==goal)
            if (x==ls[y]) R_rotate(x);
            else L_rotate(x);
        else
            if (y==ls[z])
                if (x==ls[y]) R_rotate(y),R_rotate(x);
                else L_rotate(x),R_rotate(x);
            else
                if (x==ls[y]) R_rotate(x),L_rotate(x);
                else L_rotate(y),L_rotate(x);
    }
    if (!goal) root=x;
    pushup(x);
}
int Rank(int k)
{
    int x=root;
    while (x)
    {
        pushdown(x);
        if (k<=sz[ls[x]]) x=ls[x];
        else if (k==sz[ls[x]]+1) return x;
        else k-=sz[ls[x]]+1,x=rs[x];
    }
}
int Build(int l,int r,int father)
{
    if (l>r) return 0;
    int x=Stack[top--];
    fa[x]=father;
    int mid=l+r>>1;
    if (l==r)
    {
        val[x]=sigma[x]=sum[x]=a[mid];
        pre[x]=suf[x]=max(0,a[mid]);
        sz[x]=1;return x;
    }
    val[x]=sum[x]=a[mid];
    ls[x]=Build(l,mid-1,x);
    rs[x]=Build(mid+1,r,x);
    pushup(x);
    return x;
}
void Insert()
{
    int pos=gi(),tot=gi();if (!tot) return;
    for (int i=1;i<=tot;i++) a[i]=gi();
    int L=Rank(pos+1);splay(L,0);
    int R=Rank(pos+2);splay(R,L);
    ls[R]=Build(1,tot,R);
    pushup(R);pushup(L);
}
void Clear(int x)
{
    fa[x]=ls[x]=rs[x]=0;
    val[x]=sz[x]=sigma[x]=pre[x]=suf[x]=0;sum[x]=-inf;
    rev[x]=tag[x]=0;
}
void Reuse(int x)
{
    if (!x) return;
    if (ls[x]) Reuse(ls[x]);
    if (rs[x]) Reuse(rs[x]);
    Clear(x);
    Stack[++top]=x;
}
void Delete()
{
    int pos=gi(),tot=gi();if (!tot) return;
    int L=Rank(pos);splay(L,0);
    int R=Rank(pos+tot+1);splay(R,L);
    Reuse(ls[R]);ls[R]=0;
    pushup(R);pushup(L);
}
void Make_Same()
{
    int pos=gi(),tot=gi(),c=gi();
    int L=Rank(pos);splay(L,0);
    int R=Rank(pos+tot+1);splay(R,L);
    int x=ls[R];
    val[x]=c;tag[x]=1;
    sigma[x]=sz[x]*c;
    if (c>=0) pre[x]=suf[x]=sum[x]=sigma[x];
    else pre[x]=suf[x]=0,sum[x]=c;
    pushup(R);pushup(L);
}
void Reverse()
{
    int pos=gi(),tot=gi();
    int L=Rank(pos);splay(L,0);
    int R=Rank(pos+tot+1);splay(R,L);
    int x=ls[R];
    if (!tag[x])
    {
        rev[x]^=1;
        swap(ls[x],rs[x]);
        swap(pre[x],suf[x]);
        pushup(R);pushup(L);
    }
}
void Get_Sum()
{
    int pos=gi(),tot=gi();
    int L=Rank(pos);splay(L,0);
    int R=Rank(pos+tot+1);splay(R,L);
    printf("%d\n",sigma[ls[R]]);
}
void Max_Sum()
{
    printf("%d\n",sum[root]);
}
int main()
{
    for (int i=500010;i;i--)
        Stack[++top]=i;
    n=gi();m=gi();Clear(0);
    a[1]=a[n+2]=-inf;
    for (int i=2;i<=n+1;i++) a[i]=gi();
    root=Build(1,n+2,0);
    while (m--)
    {
        scanf("%s",s);
        if (s[0]=='I') Insert();
        if (s[0]=='D') Delete();
        if (s[0]=='M'&&s[2]=='K') Make_Same();
        if (s[0]=='R') Reverse();
        if (s[0]=='G') Get_Sum();
        if (s[0]=='M'&&s[2]=='X') Max_Sum();
    }
    return 0;
}

[BZOJ1500][NOI2005]维修数列

标签:ota   ace   new   turn   pac   str   main   题目   algo   

原文地址:https://www.cnblogs.com/zhoushuyu/p/8150423.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!