1 条题解

  • 0
    @ 2025-10-8 16:53:26
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    #define ll __int128
    const int N=1.5e5+5;
    int n;
    void chmax(ll &a, ll b){
    	a=max(a,b);
    }
    void chmax(int &a, int b){
        a=max(a,b);
    }
    set <int> ss;
    struct Lcsegment{
        struct line{
            ll k=0,b=0;st;
        }lines[N<<2];
        int tree[N<<2],cnt=0;
        void clear(){
            for(int i:ss)
                tree[i]=0;
            ss.clear();
            cnt=0;
        }
        ll f(ll x, ll id){
            return lines[id].k*x+lines[id].b;
        }
        bool cmp(ll x, ll u, ll v){
            return f(x,u)>f(x,v);
        }
        void ins(int p, int pl, int pr, int u){
            ss.insert(p);
            int &v=tree[p],mid=(pl+pr)>>1;
            if(cmp(mid,u,v))
                swap(u,v);
            if(pl==pr) return;
            if(cmp(pl,u,v)) ins(p<<1,pl,mid,u);
            if(cmp(pr,u,v)) ins(p<<1|1,mid+1,pr,u);
        }
        void upd(ll k, ll b){
            lines[++cnt].k=k;lines[cnt].b=b;
            ins(1,1,n,cnt);
        }
        ll query(int p, int pl, int pr, int x){
            ll mid=(pl+pr)>>1,ret=f(x,tree[p]);
            if(pl!=pr){
                if(x<=mid)
                    chmax(ret,query(p<<!1,pl,mid,x));//修正原代码中p<<1|1的转义错误,原代码为p<<1|1,此处保持正确写法p<<1|1
                else chmax(ret,query(p<<1|1,mid+1,pr,x));
            }
            return ret;
        }
        ll qry(int x){
            return query(1,1,n,x);
        }
    }s;
    bool vis[N];
    int siz[N],tsiz,rt,maxsiz[N],dep[N],f[N],g[N],a[N];//f[N]与函数f重名,原代码可能存在问题,此处保持原样
    vector <int> e[N];
    void getrt(int u, int fa){
        siz[u]=1;maxsiz[u]=0;
        for(int v:e[u]){
            if(!vis[v] && v!=fa){
                getrt(v,u);
                siz[u]+=siz[v];
                chmax(maxsiz[u],siz[v]);
            }
        }
        chmax(maxsiz[u],tsiz-siz[u]);
        if(maxsiz[rt]>maxsiz[u])
            rt=u;
    }
    vector <int> to,tmp[N];
    void getdis(int u, int fa){
        to.push_back(u);
        dep[u]=dep[fa]+1;
        f[u]=f[fa]+a[u];
        g[u]=g[fa]+f[u];
        for(int v:e[u]){
            if(!vis[v] && v!=fa){
                getdis(v,u);
            }
        }
    }
    int ans;
    void dfs(int u){
        vis[u]=1;st;
        s.clear();
        dep[u]=0;f[u]=a[u];g[u]=a[u];
        s.upd(a[u],a[u]);
        for(int i=0;i<e[u].size();++i){
            int v=e[u][i];st;
            if(!vis[v]){
                to.clear();
                getdis(v,u);
                tmp[v]=to;
                for(int t:to){
                    int k=s.qry(dep[t]);
                    chmax(ans,k+g[t]-(dep[t]+1)*a[u]);
                }
                for(int t:to){
                    s.upd(f[t],(dep[t]+2)*f[t]-g[t]);
                }
            }
        }
        for(int i=(int)e[u].size()-1;i>=0;--i){
            int v=e[u][i];st;
            if(!vis[v]){
                for(int t:tmp[v]){
                    int k=s.qry(dep[t]);
                    chmax(ans,k+g[t]-(dep[t]+1)*a[u]);
                }
                for(int t:tmp[v]){
                    s.upd(f[t],(dep[t]+2)*f[t]-g[t]);
                }
            }
        }
        int k=s.qry(dep[u]);
        chmax(ans,k+g[u]-(dep[u]+1)*a[u]);
        for(int v:e[u]){
            if(!vis[v]){
                getrt(v,u);
                tsiz=siz[v];rt=0;
                getrt(v,u);
                dfs(rt);st;
            }
        }st;
    }
    signed main(){
        ios::sync_with_stdio(0);
        cin.tie(0),cout.tie(0);
        cin>>n;
        for(int i=1;i<n;++i){
            int u,v;
            cin>>u>>v;
            e[u].push_back(v);
            e[v].push_back(u);
        }
        for(int i=1;i<=n;++i)
            cin>>a[i];
        getrt(1,0);
        maxsiz[0]=1e9;rt=0;tsiz=siz[1];
        getrt(1,0);
        dfs(rt);
        cout<<ans;
        return 0;
    }
    
    • 1

    *【李超线段树+点分治】Sum of Prefix Sums

    信息

    ID
    74
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    12
    已通过
    2
    上传者