zoukankan      html  css  js  c++  java
  • 4515: [Sdoi2016]游戏

    4515: [Sdoi2016]游戏

    链接

    分析:

      树链剖分 + 超哥线段树。注意细节。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<cctype>
    #include<set>
    #include<vector>
    #include<queue>
    #include<map>
    #define Root 1, n, 1
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 100005;
    const LL INF = 123456789123456789ll;
    struct Edge{ int to, nxt, w; } e[N << 1];
    int head[N], dep[N], siz[N], fa[N], son[N], dfn[N], bel[N], n, En, Index;
    LL dis[N];
    struct Line{
        LL k, b;
        Line() { k = 0, b = INF; } 
        Line(LL _k,LL _b) { k = _k, b = _b; }
        LL f(LL x) { return x * k + b; }
    };
    
    inline void add_edge(int u,int v,int w) {
        ++En; e[En].to = v, e[En].w = w, e[En].nxt = head[u]; head[u] = En;
        ++En; e[En].to = u, e[En].w = w, e[En].nxt = head[v]; head[v] = En;
    }
    
    struct SegmentTree{
        LL ans[N << 2], A[N]; Line T[N << 2];
        void init() {
            for (int i = 0; i <= (N << 2); ++i) ans[i] = INF;
        }
        inline void pushup(int rt) { ans[rt] = min(ans[rt], min(ans[rt << 1], ans[rt << 1 | 1])); }
        void Cover(int l,int r,int rt,Line v) {
            int mid = (l + r) >> 1;
            if (v.f(A[mid]) < T[rt].f(A[mid])) ans[rt] = min(ans[rt], min(v.f(A[l]), v.f(A[r]))), swap(v, T[rt]); // A[l]!!!
            if (l == r) return ;
            if (v.f(A[l]) > T[rt].f(A[l]) && v.f(A[r]) > T[rt].f(A[r])) return ;
            if (v.k > T[rt].k) Cover(lson, v);
            else Cover(rson, v);
            pushup(rt);
        }
        void update(int l,int r,int rt,int L,int R,Line v) {
            if (L <= l && r <= R) { Cover(l, r, rt, v); return ; }
            int mid = (l + r) >> 1;
            if (L <= mid) update(lson, L, R, v);
            if (R > mid) update(rson, L, R, v);
            pushup(rt);
        }
        LL query(int l,int r,int rt,int L,int R) {
            if (L <= l && r <= R) return ans[rt]; // L <= r !!!
            int mid = (l + r) >> 1;
            LL res = min(T[rt].f(A[max(l, L)]), T[rt].f(A[min(r, R)]));
            if (L <= mid) res = min(res, query(lson, L, R));
            if (R > mid) res = min(res, query(rson, L, R));
            return res;
        }
    }T;
    void dfs1(int u) {
        dep[u] = dep[fa[u]] + 1;
        siz[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (v == fa[u]) continue;
            fa[v] = u;
            dis[v] = dis[u] + e[i].w;
            dfs1(v);
            siz[u] += siz[v];
            if (!son[u] || siz[son[u]] < siz[v]) son[u] = v;    
        }
    }
    void dfs2(int u,int top) {
        bel[u] = top;
        dfn[u] = ++Index; T.A[Index] = dis[u];
        if (!son[u]) return ;
        dfs2(son[u], top);
        for (int i = head[u]; i; i = e[i].nxt) 
            if (e[i].to != fa[u] && e[i].to != son[u]) dfs2(e[i].to, e[i].to);
    }
    int LCA(int u,int v) {
        while (bel[u] != bel[v]) dep[bel[u]] > dep[bel[v]] ? u = fa[bel[u]] : v = fa[bel[v]];
        return dep[u] < dep[v] ? u : v;
    }
    void Change(int u,int w,Line x) {
        while (bel[u] != bel[w]) 
        T.update(Root, dfn[bel[u]], dfn[u], x), u = fa[bel[u]];
        T.update(Root, dfn[w], dfn[u], x);
    }
    void Query() {
        int u = read(), v = read(); LL res = INF;
        while (bel[u] != bel[v]) {
            if (dep[bel[u]] < dep[bel[v]]) swap(u, v);
            res = min(res, T.query(Root, dfn[bel[u]], dfn[u]));
            u = fa[bel[u]];
        }
        if (dep[u] < dep[v]) swap(u, v);
        res = min(res, T.query(Root, dfn[v], dfn[u]));
        printf("%lld
    ", res);
    }
    int main() {
        n = read();int m = read();
        for (int i = 1; i < n; ++i) {
            int u = read(), v = read(), w = read();
            add_edge(u, v, w);
        }
        dfs1(1); dfs2(1, 1); T.init();
        while (m --) {
            int opt = read();
            if (opt == 1) {
                int u = read(), v = read(), w = LCA(u, v);LL a = read(), b = read();
                Change(u, w, Line(-a, b + dis[u] * a));
                Change(v, w, Line(a, b + a * (dis[u] - (dis[w] << 1))));
            }
            else Query();
        }
        return 0;
    }
  • 相关阅读:
    SpringMVC笔记:annotation注解式开发
    HTTP协议状态码详解(HTTP Status Code)
    SpringMVC学习笔记:SpringMVC框架的执行流程
    述一个程序员的技能:系统安装(win7版)idea配置
    Spring扩展:Spring的IoC容器(注入对象的方式和编码方式)
    Spring扩展:Spring框架的由来
    Spring学习笔记:spring整合web之spring-web架包的引用(WebApplicationContextUtils注入容器)
    Spring学习笔记:spring与mybatis四种整合方法
    MySQL修改root密码的多种方法
    为需要远程登录的用户赋予权限:
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10409002.html
Copyright © 2011-2022 走看看