zoukankan      html  css  js  c++  java
  • [洛谷P3258] [JLOI2014]松鼠的新家

    题目链接:##

    点我

    题目分析:##

    树链剖分
    每一次按顺序走到下一个点可以看作沿途的点权+1,注意出发时的点不能+1

    代码:##

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define N (600000 + 5)
    using namespace std;
    inline int read() {
        int cnt = 0, f = 1; char c;
        c = getchar();
        while (!isdigit(c)) {
            if (c == '-') f = -f;
            c = getchar();
        }
        while (isdigit(c)) {
            cnt = (cnt << 3) + (cnt << 1) + c - '0';
            c = getchar();
        }
        return cnt * f;
    }
    int son[N], siz[N], dep[N], father[N], top[N], num[N], id[N], idx;
    int first[N], nxt[N], to[N], tot;
    void Add(int x, int y) {
        nxt[++tot] = first[x];
        first[x] = tot;
        to[tot] = y;
    }
    
    void dfs1(int cur, int fa) {
        father[cur] = fa, siz[cur] = 1, dep[cur] = dep[fa] + 1;
        for (register int i = first[cur]; i; i = nxt[i]) {
            int v = to[i];	
            if (v != fa) {
                dfs1(v, cur);
                siz[cur] += siz[v];
                if (siz[son[cur]] < siz[v]) son[cur] = v;
            }
        }
    }
    
    void dfs2(int cur, int tp) {
        top[cur] = tp; num[cur] = ++idx; id[idx] = cur;
        if (son[cur]) dfs2(son[cur], tp);
        for (register int i = first[cur]; i; i = nxt[i]) {
            int v = to[i];
            if (!num[v]) dfs2(v, v);
        }
    }
    
    struct node {
        int l; int r;
        int sum, tag;
        #define l(p) tree[p].l
        #define r(p) tree[p].r
        #define sum(p) tree[p].sum
        #define tag(p) tree[p].tag
    }tree[N * 4];
    
    void push_up(int p) {
        sum(p) = sum(p << 1) + sum(p << 1 | 1);
    }
    
    void push_down(int p) {
        sum(p << 1) += (r(p << 1) - l(p << 1) + 1) * tag(p);
        sum(p << 1 | 1) += (r(p << 1 | 1) - l(p << 1 | 1) + 1) * tag(p);
        tag(p << 1) += tag(p); tag(p << 1 | 1) += tag(p);
        tag(p) = 0; 
    }
    
    void build_tree(int p, int l, int r) {
        l(p) = l; r(p) = r;
        if (l == r) {
            sum(p) = 0; return;
        }
        int mid = (l + r) >> 1;
        build_tree(p << 1, l, mid);
        build_tree(p << 1 | 1, mid + 1, r);
        push_up(p);
    }
    
    void modify (int p, int l, int r, int d) {
        if (l <= l(p) && r >= r(p)) {
            tag(p) += d;
            sum(p) += (r(p) - l(p) + 1) * d;
            return;
        }
        push_down(p);
        int mid = (l(p) + r(p)) >> 1;
        if (l <= mid) modify(p << 1, l, r, d);
        if (r > mid) modify(p << 1 | 1, l, r, d);
        push_up(p);
    }
    
    int query (int p, int l, int r) {
        if (l <= l(p) && r >= r(p)) return sum(p);
        push_down(p);
        int val = 0;
        int mid = (l(p) + r(p)) >> 1;
        if (l <= mid) val += query(p << 1, l, r);
        if (r > mid) val += query(p << 1 | 1, l, r);
        return val;
    }
    
    void chain_modify(int u, int v, int d) {
        while (top[u] != top[v]) {
            if (dep[top[u]] < dep[top[v]]) swap(u, v);
            modify(1, num[top[u]], num[u], d);
            u = father[top[u]];
        }
        if (dep[u] < dep[v]) swap(u, v);
        modify(1, num[v], num[u], d);
    }
    
    int n, A[N], x, y;
    int main() {
        n = read(); 
        for (register int i = 1; i <= n; i++) A[i] = read();
        for (register int i = 1; i < n; i++) {
            x = read(); y = read();
            Add(x, y); Add(y, x);
        }
        dfs1(1, 0); dfs2(1, 1);build_tree(1, 1, n);
        for (register int i = 1; i < n; i++) chain_modify(A[i], A[i + 1] , 1);
        for (register int i = 1; i <= n; i++) {
            if (i != A[1]) 
            printf("%d
    ", query(1, num[i], num[i]) - 1);
            else printf("%d
    ", query(1, num[i], num[i]));
        }
        return 0;
    }
    
  • 相关阅读:
    Maven3核心技术(笔记三)
    解决Ubuntu下Sublime Text 3无法输入中文
    python3项目之数据可视化
    Python模块Pygame安装
    PHP命名空间(Namespace)
    git的安装使用和代码自动部署
    input:text 的value 和 attribute('value') 不是一回事
    touch事件学习
    获得 选中文字
    linux使用crontab实现PHP执行定时任务及codeiginter参数传递相关
  • 原文地址:https://www.cnblogs.com/kma093/p/11097725.html
Copyright © 2011-2022 走看看