zoukankan      html  css  js  c++  java
  • CF.739B 【Alyona and a tree】(倍增+树上差分/二分树上差分)

    题目链接:https://codeforces.com/contest/739/problem/B

    题意:一棵根节点为1的树,每个点都有点值a[i],每条边也有权值,dist(v, u)表示从v到u边权和,当u时v的子孙并且dist(v, u)<=a[u]时u就受v控制,输出每个结点能控制的结点数。

    解法1:倍增+树上差分

    一开始不知道该怎么去写这个树上差分,后来看了别人的题解报告算是明白了。一开始就是简单的倍增,同时求出每个点x到1的距离,即d[x]=dis(1,x)。完成第一步dfs之后,就是把当前点x不断向上跳,比如跳到y了,dis(x,y)=d[x]-d[y]刚好<a[x],那么也就是说x~y里面所有的点(除去x)都可以控制x,那么就把y的父亲差分数组-1,x的父亲差分数组+1即可。

    #include<bits/stdc++.h>
    #pragma GCC optimize(2)
    #define ll long long
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define per(i,n,a) for(int i=n;i>=a;i--)
    #define endl '
    '
    #define eps 0.000000001
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    const int INF=0x3f3f3f3f;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int tot,head[maxn];
    struct E{
        int to,next,w;
    }edge[maxn<<1];
    void add(int u,int v,int w){
        edge[tot].to=v;
        edge[tot].w=w;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    int n,a[maxn];
    int fa[maxn][40],vis[maxn],depth[maxn],d[maxn];
    void dfs(int x,int step){
        depth[x]=step;vis[x]=1;
        for(int i=head[x];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(vis[v]) continue;
            fa[v][0]=x;
            d[v]=d[x]+edge[i].w;
            dfs(v,step+1);
        }
    }
    void bz(){
        for(int j=1;j<=30;j++){
            for(int i=1;i<=n;i++){
                fa[i][j]=fa[fa[i][j-1]][j-1];
            }
        }
    }
    int C[maxn];
    void solve(int x,int f){
        for(int i=head[x];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(v==f) continue;
            solve(v,x);
            C[x]+=C[v];
        }
    }
    int main(){
        scanf("%d",&n);mem(head,-1);
        rep(i,1,n) scanf("%d",&a[i]);
        rep(i,2,n){
            int p,w;scanf("%d%d",&p,&w);
            add(i,p,w);add(p,i,w);
        }    
        dfs(1,1);
        bz();
        for(int i=1;i<=n;i++){
            int now=i,dis=a[i];
            for(int j=19;j>=0;j--){
                if(d[now]-d[fa[now][j]]<=dis){
                    dis+=(d[fa[now][j]]-d[now]);
                    now=fa[now][j];
                }
            }
            C[fa[i][0]]++;C[fa[now][0]]--;
        }
        solve(1,0);
        rep(i,1,n){
            printf("%d ",C[i]);
        }
        puts("");
    }
    View Code
    Codeforces ID:Anonytt QQ: 847399102 可以添加&关注
  • 相关阅读:
    java.lang.NoSuchMethodError:antlr.collections.AST.getLine() I
    T7 java Web day01 标签HTML
    T6 s1 day19
    T5 s5 Day18
    T5 s4 Day 17
    T5 s3 day16
    T5 s2 Day 15
    T5 s1 day14
    T4 S03 day 12
    T4 S01 day1
  • 原文地址:https://www.cnblogs.com/Anonytt/p/13585129.html
Copyright © 2011-2022 走看看