Atcoder AGC008F : Black Radius(DP)

Portal

Explanation:
Binary (x,d)(x,d) is defined as a dyeing scheme with x x as the key point and D D as the maximum distance.
Consider all black dots first:
Let f(x,d)f(x,d) denote the set of points whose distance from x x does not exceed D D. Let's assume that f(x,d)f(x,d) is not a complete set, so the answer is to a dd 1 to the number of all essentially different sets f(x,d) because the complete set is always a legitimate dyeing scheme.
It is obviously incorrect to calculate directly how many DDS are a dd ed up for each xx, because there will be essentially the same scheme to be repeated.
We consider when the dyeing scheme (i,d1)(i,d1) (i,d1)(i,d1) and dyeing scheme (i,d1)(i,d1) and (j,d2)(j,d2) will repeat for each pair of points (i,j)(i,j) (i, j, d1) =f (i, d1) =f (j, d2) S = f (j, d2) S = f (i, d1) =f (i, d1) =f (i, d1) =f (j, d1\8722dist (i, k) =S f(x,d18722dist (i, d18722dist (i, k) = (i, d1) and (dist (i, dist (i, disRepresents the distance between I I and K K on a tree. So we can find the node kk which is closest to II on the path (i.e. adjacent to ii), and only need to care about these nodes.
We try to calculate how many DDS satisfy f(i,d)f(i,d) without duplicating any f(j,d2)f(j,d2). It is said that:
1. f(i,d)f(i,d) is not a complete set.
2. For any k k adjacent to I i, f (i, d)f(k,d_1) f (i, d)f(k,d_1).
The solution of the first condition is very simple. For each node ii, we find the distance Disi Disi from II to the farthest node on the tree, then d < [0,disi 1]d < [0,disi 1].
The second condition can be equivalent to that in the scheme (i,d)(i,d), the tree rooted by I I is black except for the nodes in the subtree where k k is located, and those nodes in the scheme (k,d_1)(k,d_1) are also black. For each edge (i,k)(i,k), we find the distance dis2(i,k)dis2(i,k) from I I without K K to the farthest node on the tree, then d <[0, dis2 i, k+1]. D [0,dis2i,k+1].
The calculation of disidisi and dis2(i,k)dis2(i,k) can be solved in O(N)O(N) time by simple tree DP.

Nowadays, some nodes can not be selected directly. We need to reconsider what conditions f(i,d)f(i,d) need to satisfy to be a legal dyeing scheme:
1. If ii is a special node, dd can be an arbitrary natural number.
2. If I I is not a special node, considering I I as the root of the whole tree, then if there is a special node jj satisfaction scheme (i,d)(i,d), all nodes in the subtree where jj is located are dyed black, (i,d)(i,d) is a legal dyeing scheme. So we only need to find the minimum distance from ii to the farthest node in the jj subtree through at least 11 special nodes, which is the minimum feasible dd. This can also be solved by simple tree DP in O(N)O(N) time.
After finding the lower bound of dd for each node ii, the problem becomes the previous one.

#include <bits/stdc++.h>
using namespace std;
inline int rd() {
    char ch=getchar(); int i=0,f=1;
    while(!isdigit(ch)) {if(ch=='-')f=-1; ch=getchar();}
    while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=getchar();}
    return i*f;
}
const int N=2e5+50,INF=0x3f3f3f3f;
int n,col[N],fa[N],sze[N];
int d1[N]; //Farthest point of subtree
int d2[N]; //Father's farthest point
int d3[N]; //The nearest point of a subtree passing through a black spot
int d4[N]; //Father's nearest point after a black spot
int d5[N]; //Not passing the farthest point of a subtree
int d6[N]; //Lower bound 
vector <int> edge[N]; 
inline void dfs1(int x,int f) {
    fa[x]=f; sze[x]=col[x];
    if((x!=1 && edge[x].size()==1) || (x==1 && !edge[x].size())) {
        d1[x]=0; 
        d3[x]=(col[x]?0:INF);
        return;
    }
    int mx=0,mx2=INF;
    for(auto v:edge[x]) {
        if(v==f) continue;
        dfs1(v,x); sze[x]+=sze[v];
        mx=max(mx,d1[v]); 
        if(d3[v]<INF) mx2=min(mx2,d1[v]);
    }
    d1[x]=mx+1; d3[x]=mx2+1; 
    if(col[x]) d3[x]=min(d3[x],d1[x]); 
}
inline void dfs2(int x,int f) {
    d2[x]=max(d2[x],(f!=0)+d2[f]);
    if(f) d5[x]=max(d5[x],d2[x]-1);
    int mx,mx2;
    mx=-1;
    for(int e=0;e<edge[x].size();++e) {
        int v=edge[x][e]; if(v==f) continue;
        d2[v]=max(d2[v],mx+2);
        mx=max(mx,d1[v]);
    }
    mx=-1;
    for(int e=edge[x].size()-1;e>=0;e--) {
        int v=edge[x][e]; if(v==f) continue;
        d2[v]=max(d2[v],mx+2);
        mx=max(mx,d1[v]);
    }
    for(auto v:edge[x]) if(v!=f) dfs2(v,x);
}
int main() { 
    n=rd();
    memset(d3,0x3f,sizeof(d3));
    memset(d4,0x3f,sizeof(d4));
    for(int i=1;i<n;i++) {
        int x=rd(), y=rd();
        edge[x].push_back(y);
        edge[y].push_back(x); 
    }
    string s; cin>>s; int bz=0;
    for(int i=0;i<n;i++) col[i+1]=s[i]-'0', bz|=col[i+1];
    if(!bz) {puts("0"); return 0;}
    dfs1(1,0); 
    dfs2(1,0);
    long long ans=0;
    for(int i=1;i<=n;i++) {
        if(col[i]) d6[i]=0;
        else d6[i]=min(d3[i],(sze[i]==sze[1])?INF:d2[i]);
        int u=max(d1[i],d2[i])-1;
        for(auto v:edge[i]) {
            if(v==fa[i]) u=min(u,d1[i]+1);
            else u=min(u,d5[v]+1);
        } 
        if(u>=d6[i]) ans=ans+u-d6[i]+1;
    }
    cout<<ans+1;
}

Posted by eskick on Sat, 05 Jan 2019 23:03:10 -0800