zoukankan      html  css  js  c++  java
  • Luogu 3066 [USACO12DEC]逃跑的BarnRunning Away From…

    好像是某CF的题,不记得……

    很套路的题,但是觉得可以做一下笔记。

    倍增 + 差分。

    有一个比较简单的思路就是每一个点$x$向上走一走,直到走到一个点$y$使总路程恰好不超过超过了$L$,然后把$(x, y)$这条链上的答案$ + 1$。

    可以用倍增优化走一走的过程,可以用差分实现把一条向上的树链$+ 1$的操作。

    时间复杂度$O(nlogn)$。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    const int N = 2e5 + 5;
    const int Lg = 20;
    
    int n, tot = 0, head[N], fa[N][Lg], f[N];
    ll cur, dis[N][Lg];
    
    struct Edge {
        int to, nxt;
        ll val;
    } e[N << 1];
    
    inline void add(int from, int to, ll val) {
        e[++tot].to = to;
        e[tot].val = val;
        e[tot].nxt = head[from];
        head[from] = tot;
    }
    
    template <typename T>
    inline void read(T &X) {
        X = 0; char ch = 0; T op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    void dfs(int x, int fat, ll nowDis) {
        fa[x][0] = fat, dis[x][0] = nowDis;
        for(int i = 1; i <= 18; i++) {
            fa[x][i] = fa[fa[x][i - 1]][i - 1];
            dis[x][i] = dis[x][i - 1] + dis[fa[x][i - 1]][i - 1];
        }
        for(int i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to;
            if(y == fat) continue;
            dfs(y, x, e[i].val);
        }
    } 
    
    inline int getPos(int x) {
        ll nowDis = 0LL;
        for(int i = 18; i >= 0; i--)
            if(nowDis + dis[x][i] <= cur) {
                nowDis += dis[x][i];
                x = fa[x][i];
            }
        return x;
    } 
    
    void solve(int x, int fat) {
        for(int i = head[x]; i; i = e[i].nxt) {
            int y = e[i].to;
            if(y == fat) continue;
            solve(y, x);
            f[x] += f[y];
        }
    }
    
    int main() {
        read(n), read(cur);
        for(int i = 2; i <= n; i++) {
            int fat; ll v;
            read(fat), read(v); 
            add(fat, i, v), add(i, fat, v);
        }
        dfs(1, 0, 0LL);
        
    /*    for(int i = 1; i <= n; i++)
            printf("%d ", dis[i][18]);   */
        
        for(int i = 1; i <= n; i++) {
            ++f[i];
            int pos = getPos(i);
            --f[fa[pos][0]];
        }
        
        solve(1, 0);
        
        for(int i = 1; i <= n; i++)
            printf("%d
    ", f[i]);
        
        return 0;
    }
    View Code
  • 相关阅读:
    专职DBA-MySQL体系结构与基本管理
    JSON
    MIME类型
    文件上传下载
    response常用的方法
    2020.11.27小记
    HTTP请求状态码
    1561. Maximum Number of Coins You Can Get
    1558. Minimum Numbers of Function Calls to Make Target Array
    1557. Minimum Number of Vertices to Reach All Nodes
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9848202.html
Copyright © 2011-2022 走看看