zoukankan      html  css  js  c++  java
  • 【LOJ】#3036. 「JOISC 2019 Day3」指定城市

    LOJ#3036. 「JOISC 2019 Day3」指定城市

    一个点的可以dp出来

    两个点也可以dp出来

    后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 200005
    #define ba 47
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
        	if(c == '-') f = -1;
        	c = getchar();
        }
        while(c >= '0' && c <= '9') {
        	res = res * 10 +c - '0';
        	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
        	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    struct node {
        int to,next;int64 val;
    }E[MAXN * 2];
    int head[MAXN],sumE,N;
    int64 ans[MAXN],all;
    void add(int u,int v,int c) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        E[sumE].val = c;
        head[u] = sumE;
    }
    
    
    namespace one {
        int64 dis[2][MAXN],fir;
        void dfs(int u,int fa) {
            for(int i = head[u] ; i ; i = E[i].next) {
                int v = E[i].to;
                if(v == fa) {dis[1][u] = dis[1][fa] + E[i].val;fir += E[i].val;}
                else dis[0][v] = dis[0][u] + E[i].val;
            }
            for(int i = head[u] ; i ; i = E[i].next) {
                int v = E[i].to;
                if(v != fa) dfs(v,u);
            }
        }
        void Main() {
            dfs(1,0);
            int64 res = fir;
            for(int i = 2 ; i <= N ; ++i) {
                res = max(res,fir + dis[0][i] - dis[1][i]);
            }
            ans[1] = all - res;
        }
    }
    namespace two {
        int64 dis[2][MAXN],fir,mval = 0;
        pair<int64,int> dp[MAXN];
        int siz[MAXN],dfn[MAXN],idx,line[MAXN],fa[MAXN],S = 1,T = 1;
        bool vis[MAXN];
        struct node {
            int l,r,pos;int64 mv,lz;
        }tr[MAXN * 4];
        void dfs(int u) {
            siz[u] = 1;dfn[u] = ++idx;line[idx] = u;
            for(int i = head[u] ; i ; i = E[i].next) {
                int v = E[i].to;
                if(v == fa[u]) {dis[1][u] = dis[1][fa[u]] + E[i].val;fir += E[i].val;}
                else dis[0][v] = dis[0][u] + E[i].val;
            }
            dp[u] = mp(0,u);
            for(int i = head[u] ; i ; i = E[i].next) {
                int v = E[i].to;
                if(v != fa[u]) {
                    fa[v] = u;
                    dfs(v);
                    siz[u] += siz[v];
                    if(E[i].val + dp[v].fi + dp[u].fi - dis[1][u] + dis[0][u] > mval) {
                        mval = E[i].val + dp[v].fi + dp[u].fi - dis[1][u] + dis[0][u];
                        S = dp[u].se;T = dp[v].se;
                    }
                    if(dp[v].fi + E[i].val > dp[u].fi) {
                        dp[u].fi = dp[v].fi + E[i].val;dp[u].se = dp[v].se;
                    }
                }
            }
        }
        void update(int u) {
            if(tr[u << 1].mv > tr[u << 1 | 1].mv) {
                tr[u].mv = tr[u << 1].mv;
                tr[u].pos = tr[u << 1].pos;
            }
            else {
                tr[u].mv = tr[u << 1 | 1].mv;
                tr[u].pos = tr[u << 1 | 1].pos;
            }
        }
        void addlz(int u,int64 v) {
            tr[u].mv += v;tr[u].lz += v;
        }
        void pushdown(int u) {
            if(tr[u].lz) {
                addlz(u << 1,tr[u].lz);
                addlz(u << 1 | 1,tr[u].lz);
                tr[u].lz = 0;
            }
        }
        void build(int u,int l,int r) {
            tr[u].l = l;tr[u].r = r;
            if(l == r) {
                tr[u].mv = dis[0][line[l]];tr[u].pos = line[l];
                return;
            }
            int mid = (l + r) >> 1;
            build(u << 1,l,mid);
            build(u << 1 | 1,mid + 1,r);
            update(u);
        }
        void Add(int u,int l,int r,int64 v) {
            if(tr[u].l == l && tr[u].r == r) {addlz(u,v);return;}
            pushdown(u);
            int mid = (tr[u].l + tr[u].r) >> 1;
            if(r <= mid) Add(u << 1,l,r,v);
            else if(l > mid) Add(u << 1 | 1,l,r,v);
            else {Add(u << 1,l,mid,v);Add(u << 1 | 1,mid + 1,r,v);}
            update(u);
        }
        int64 Query(int u,int pos) {
            if(tr[u].l == tr[u].r) return tr[u].mv;
            pushdown(u);
            int mid = (tr[u].l + tr[u].r) >> 1;
            if(pos <= mid) return Query(u << 1,pos);
            else return Query(u << 1 | 1,pos);
        }
        void Delete(int u) {
            int pre = 0;
            while(u && !vis[u]) {
                int64 t = Query(1,dfn[u]);
                if(!pre) Add(1,dfn[u],dfn[u] + siz[u] - 1,-t);
                else {
                    Add(1,dfn[u],dfn[pre] - 1,-t);
                    if(dfn[pre] + siz[pre] <= dfn[u] + siz[u] - 1)
                        Add(1,dfn[pre] + siz[pre],dfn[u] + siz[u] - 1,-t);
                }
                vis[u] = 1;
                pre = u;u = fa[u];
            }
        }
        void More(int x) {
            ans[x] = ans[x - 1] - tr[1].mv;
            Delete(tr[1].pos);
        }
        void Main() {
            dfs(1);
            ans[2] = all - (fir + mval);
            memset(dis,0,sizeof(dis));
            fa[S] = 0;idx = 0;
            dfs(S);
            build(1,1,N);
            Delete(T);
        }
    
    }
    void Solve() {
        read(N);
        int a,b,c,d;
        for(int i = 1 ; i < N ; ++i) {
            read(a);read(b);read(c);read(d);
            add(a,b,c);
            add(b,a,d);
            all += c;all += d;
        }
        one::Main();
        if(N >= 2) two::Main();
        for(int i = 3 ; i <= N ; ++i) {
            two::More(i);
        }
        int Q;
        read(Q);
        for(int i = 1 ; i <= Q ; ++i) {
            read(a);
            out(ans[a]);enter;
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
        return 0;
    }
    
  • 相关阅读:
    起点中文网小说爬取-etree,xpath,os
    拉勾网爬虫--待改正
    破解有道词典翻译-版本二
    pycharm错误:11001
    自动化selenium 测试之道(一)
    valgrind 详细说明
    sar命令使用详解
    Linux CPU实时监控mpstat命令详解
    Linux IO实时监控iostat命令详解
    RPM安装命令总结
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10957585.html
Copyright © 2011-2022 走看看