HDU 5788 Level Up

来源:互联网 发布:hbuilder下载 mac 编辑:程序博客网 时间:2024/04/30 12:26

Description

The Arithmetic Coconut Median company has n employees. Every person has a direct supervisor except the boss. Boss’s number is 1. Everyone has a Ability Value Ai. The wage of person i is the Median of Ability Value of person i and his (direct and indirect) subordinates. The ACM company decided to send a person to study in the center of the universe, then the Ability Value of this person will become 100000.
Please calculate the maximum sum of wages of all people.
Define the Median of t integers: the t2 th smallest number of these t integers.

Solution

这题数据似乎十分的水,完全错的就可以直接过掉所有数据了

首先我们对于每个节点,如果它的子树中比原中位数小的点点权被修改,则其中位数位置向后滑动1

也就是说我们可以一开始predfs出每个点的mid+1和mid的差值,在dfs到某节点的时候观察差值被修改的最大值。

查询中位数可以用主席树,dfs过程找最大差值可以用权值BIT

Code

#include<iostream>#include<string.h>#include<stdio.h>#include<algorithm>#include<time.h>#include<stdlib.h>#include<math.h>#include<string>#include<vector>#include<queue>#include<stack>#include<set>#include<map>using namespace std;typedef double db;typedef unsigned ud;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;#define fi first #define se second#define pb push_back#define ph pushconst int INF=(ud)-1>>1;const ll inf=(ull)-1>>1;template<class T>void rd(T &a){    a=0;char c;    while(c=getchar(),!isdigit(c));    do a=a*10+(c^48);        while(c=getchar(),isdigit(c));}template<class T>void nt(T x){    if(!x)return;    nt(x/10);    putchar(48+x%10);}template<class T>void pt(T x){    if(!x)putchar('0');    else nt(x);}template<class T>void Max(T &a,T b){    if(a<b)a=b;}template<class T>void Min(T &a,T b){    if(a==-1||a>b)a=b;}const int M=1e5+5;const int N=2e6+5;const int P=1e5;int n,Lim;struct Chairman_Tree{    int ls[N],rs[N],cnt[N],allc;    inline void clear(){        for(int i=1;i<=allc;++i)            ls[i]=rs[i]=cnt[i]=0;        allc=0;    }    inline void update(int &rt,int ot,int s,int l=1,int r=Lim){        rt=++allc;        ls[rt]=ls[ot],rs[rt]=rs[ot],cnt[rt]=cnt[ot]+1;        if(l==r)return;        int mid=l+r>>1;        if(s<=mid)update(ls[rt],ls[ot],s,l,mid);        else update(rs[rt],rs[ot],s,mid+1,r);    }    inline int query(int rt,int ot,int s,int l=1,int r=Lim){//询问第s小        if(l==r)return l;        int mid=l+r>>1;        int w=cnt[ls[rt]]-cnt[ls[ot]];        if(s<=w)return query(ls[rt],ls[ot],s,l,mid);        else return query(rs[rt],rs[ot],s-w,mid+1,r);    }}ct;struct BIT{    int bit[M];    inline void add(int x,int a){        for(;x<=Lim;x+=x&-x)bit[x]+=a;    }    inline ll sum(int x){        ll res=0;        for(;x;x-=x&-x)res+=bit[x];        return res;    }    inline void clear(){        memset(bit,0,sizeof(bit));    }}T;int A[M],f[M];struct Edge{    int to,nxt;}G[M<<1];int head[M],tot_edge;inline void add_edge(int from,int to){    G[tot_edge]=(Edge){to,head[from]};    head[from]=tot_edge++;}int rt[M],dfn[M],dfs_clock,val[M],mid[M],sz[M];ll sum,Mx;inline void predfs(int v){    dfn[v]=++dfs_clock;    ct.update(rt[dfs_clock],rt[dfs_clock-1],A[v]);    sz[v]=1;    for(int i=head[v];~i;i=G[i].nxt){        int to=G[i].to;        predfs(to);        sz[v]+=sz[to];    }    int s=sz[v]+1>>1;    int w1=0,w2=0;    w1=ct.query(rt[dfs_clock],rt[dfn[v]-1],s);    if(~head[v])w2=ct.query(rt[dfs_clock],rt[dfn[v]-1],s+1);    mid[v]=w1,val[v]=max(0,w2-w1);    sum+=w1;}inline void dfs(int v){    T.add(mid[v],val[v]);    ll w=T.sum(Lim)-T.sum(A[v]-1);    if(head[v]==-1)w+=P-A[v];    Max(Mx,w);    for(int i=head[v];~i;i=G[i].nxt)        dfs(G[i].to);    T.add(mid[v],-val[v]);}inline void gao(){    memset(head,-1,sizeof(head));    sum=Mx=tot_edge=dfs_clock=Lim=0;    ct.clear(),T.clear();    memset(rt,0,sizeof(rt));    for(int i=1;i<=n;++i)rd(A[i]),Max(Lim,A[i]);    for(int i=2;i<=n;++i)        rd(f[i]),add_edge(f[i],i);    predfs(1);    dfs(1);    cout<<sum+Mx<<endl;}//#define LOCALint main(){#ifdef LOCAL    freopen("1008.in","r",stdin);    freopen("ans.out","w",stdout);    int size = 256 << 20; // 256MB    char *p = (char*)malloc(size) + size;    __asm__("movl %0, %%esp\n" :: "r"(p));#endif    for(;cin>>n;)gao();    return 0;}
0 0
原创粉丝点击