首页 > 其他 > 详细

AC日记——最小正子段和 51nod 1065

时间:2017-04-25 22:58:06      阅读:255      评论:0      收藏:0      [点我收藏+]

最小正子段和

 

思路:

  找最小的大于0的sum[j]-sum[i](j>i);

  高级数据结构(splay)水过;

 

来,上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define maxn 50005
#define ll long long
#define INF 0x7fffffff

struct TreeNodeType {
    ll w,key,opi,size,ch[2];
};
struct TreeNodeType tree[maxn];

ll n,tot,root,sum[maxn],ans=INF;

inline void in(ll &now)
{
    ll if_z=1;now=0;
    char Cget=getchar();
    while(Cget>9||Cget<0)
    {
        if(Cget==-) if_z=-1;
        Cget=getchar();
    }
    while(Cget>=0&&Cget<=9)
    {
        now=now*10+Cget-0;
        Cget=getchar();
    }
    now*=if_z;
}

inline ll getson(ll x)
{
    return x==tree[tree[x].opi].ch[1];
}

inline void updata(ll x)
{
    tree[x].size=tree[x].w;
    if(tree[x].ch[0]) tree[x].size+=tree[tree[x].ch[0]].size;
    if(tree[x].ch[1]) tree[x].size+=tree[tree[x].ch[1]].size;
}

void rotate(ll now)
{
    ll opi=tree[now].opi,fopi=tree[opi].opi,pos=getson(now);
    tree[opi].ch[pos]=tree[now].ch[pos^1];
    if(tree[opi].ch[pos]) tree[tree[opi].ch[pos]].opi=opi;
    tree[now].ch[pos^1]=opi,tree[now].opi=fopi;
    if(opi) tree[fopi].ch[getson(opi)]=now;
    tree[opi].opi=now,updata(opi),updata(now);
}

void splay(ll now)
{
    if(now==root) return ;
    for(ll opi;opi=tree[now].opi;rotate(now))
    {
        if(tree[opi].opi) rotate(getson(now)==getson(opi)?opi:now);
    }
    root=now;
}

void insert(ll x)
{
    if(!root)
    {
        root=++tot;
        tree[root].w=1;
        tree[root].key=x;
        tree[root].size=1;
        return ;
    }
    ll now=root,opi=0;
    while(1)
    {
        if(x==tree[now].key)
        {
            tree[now].w++,tree[now].size++;
            splay(now);
            return ;
        }
        opi=now,now=tree[now].ch[x>tree[now].key];
        if(now==0)
        {
            now=++tot;
            tree[now].w=1;
            tree[now].key=x;
            tree[now].size=1;
            tree[now].opi=opi;
            tree[opi].ch[x>tree[opi].key]=now;
            splay(now);
            return ;
        }
    }
}

ll pre()
{
    if(tree[root].w>1) return tree[root].key;
    ll now=tree[root].ch[0];if(!now) return 0;
    while(tree[now].ch[1]!=0) now=tree[now].ch[1];
    return tree[now].key;
}

int main()
{
    in(n);insert(0);
    for(ll i=1;i<=n;i++)
    {
        in(sum[i]);
        sum[i]+=sum[i-1];
        insert(sum[i]);
        ll pos=pre();
        if(sum[i]-pos>0) ans=min(ans,sum[i]-pos);
    }
    cout<<ans;
    return 0;
}

 

AC日记——最小正子段和 51nod 1065

原文:http://www.cnblogs.com/IUUUUUUUskyyy/p/6764962.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!