首页 > 代码库 > AC日记——最小正子段和 51nod 1065

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

最小正子段和

 

思路:

  找最小的大于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 0x7fffffffstruct 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