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

[FJOI2018]领导集团问题

时间:2019-06-24 21:10:15      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:oid   main   scan   pac   lead   void   std   scanf   cstring   

https://www.luogu.org/problemnew/show/P4577

带区间修改的线段树合并

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=200005;
int n,i,j,w[N],ch[N*31][2],mx[N*31],add[N*31],cnt,root[N],head[N],adj[N],nxt[N];//数组别开小了
void pushdown(int o,int l,int r)
{
    if(add[o])
    {
        if(ch[o][0])
            add[ch[o][0]]+=add[o],mx[ch[o][0]]+=add[o];
        if(ch[o][1])
            add[ch[o][1]]+=add[o],mx[ch[o][1]]+=add[o];
        add[o]=0;
    }
}
void merge(int &o1,int o2,int l,int r,int x,int y)
{
    if(!o2)
    {
        add[o1]+=y;
        mx[o1]+=y;
        return;
    }
    if(!o1)
    {
        o1=o2;
        add[o1]+=x;
        mx[o1]+=x;
        return;
    }
    if(l==r)
    {
        x=max(x,mx[o1]),y=max(y,mx[o2]);
        mx[o1]=max(mx[o1]+y,mx[o2]+x);
        return;
    }
    int mid=l+r>>1;
    pushdown(o1,l,r);
    pushdown(o2,l,r);
    mx[0]=0;
    int X=max(x,mx[ch[o1][1]]),Y=max(y,mx[ch[o2][1]]);
    merge(ch[o1][0],ch[o2][0],l,mid,X,Y);
    merge(ch[o1][1],ch[o2][1],mid+1,r,x,y);
    mx[0]=0;
    mx[o1]=max(mx[ch[o1][0]],mx[ch[o1][1]]);
}
void update(int &o,int l,int r,int x,int y)
{
    if(!o)
        o=++cnt;
    if(l==r)
    {
        mx[o]=max(mx[o],y+1);
        return;
    }
    pushdown(o,l,r);
    int mid=l+r>>1;
    if(x<=mid)
        update(ch[o][0],l,mid,x,y);
    else
        update(ch[o][1],mid+1,r,x,y);
    mx[0]=0;
    mx[o]=max(mx[ch[o][0]],mx[ch[o][1]]);
}
int query(int o,int l,int r,int x,int y)
{
    if(!o)
        return 0;
    if(l>=x&&r<=y)
        return mx[o];
    int mid=l+r>>1,rtn=0;
    pushdown(o,l,r);
    if(x<=mid)
        rtn=query(ch[o][0],l,mid,x,y);
    if(y>mid)
        rtn=max(rtn,query(ch[o][1],mid+1,r,x,y));
    return rtn;
}
void dfs(int x)
{
    for(int y=head[x];y;y=nxt[y])
    {
        dfs(adj[y]);
        if(!root[x])
            root[x]=root[adj[y]];
        else
            merge(root[x],root[adj[y]],0,1000000000,0,0);
    }
    update(root[x],0,1000000000,w[x],query(root[x],0,1000000000,w[x],1000000000));
}
int main()
{
    freopen("leader.in","r",stdin);
    freopen("leader.out","w",stdout);
    scanf("%d",&n);
    for(i=1;i<=n;++i)
        scanf("%d",w+i);
    for(i=1;i<n;++i)
    {
        scanf("%d",&j);
        adj[i]=i+1;
        nxt[i]=head[j];
        head[j]=i;
    }
    dfs(1);
    printf("%d",mx[root[1]]);
    return 0;
}

 

[FJOI2018]领导集团问题

标签:oid   main   scan   pac   lead   void   std   scanf   cstring   

原文地址:https://www.cnblogs.com/pthws/p/11079222.html

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