[HNOI 2014] Luo World Tree Valley P3233

Problem Description

World tree is a very great tree, its branches extending form the entire world. Here, living with a variety of races and creatures, they jointly believe in the absolute fair and equitable goddess Alison, in their creed, the fair is to make the world a tree can be endless, continuous operation of the fundamental cornerstone.
Formations of the tree can be used a mathematical model to describe: World tree there are n racial, ethnic numbered from 1 to n, are living in numbered 1 to n settlements on the ground, the same race number of its settlements in the number . Have linked two-way street between some settlements, the road length is 1. Guarantee means connected to form a tree structure, all of which can reach each other settlements, and the ring does not occur. It defines the distance between the two connected colony their path length; e.g., if there is a settlement between the road and b, b, and C between the roads, because the length of each road and has an impossible ring, the horizontal distance between a and c is 2.
For reasons of fairness, i year, the king of the world tree requires authorization m [i] races at temporary settlements procedure. For a racial x (x for the race number), if y (y is point of procedure where the number of colonies) away from the race at the recent provisional rules of procedure, for the race will be governed at x y Procedure (If more temporary distance to the procedure of the settlement of the same, wherein the number y is at a minimum provisional procedure).
King would like to know, in q-year period, after the completion of each year mandate each year at the provisional rules of procedure will be how many races management (where the rules of procedure of the settlements will also be accepted at the Management Procedure). Now this task to the wisdom of primates known for you: program ape. Please help the king to complete the task bar.

Input Format

The first line a positive integer n, the number of trees in the race world.
Next nl row, each row two positive integers x, y, x represents a settlement between the colony and y has a double length 1 of
the road. Next, a behavior of a positive integer q, represents the number of years the king asked.
Next q blocks, each two lines:
a first block i acts positive integer of 1 m [i], represents the number of i-th provisional at the procedure of authorization.
The second line of the i-th block m [i] a positive integer h [l], h [2 ], ..., h [m [i]], expressed as the colony number is authorized at the provisional procedure (guaranteed mutually different ).

Output Format

Comprising an output line q, the behavior of the i m [i] integer, the j-th row (j = 1,2 ... ,, m [i]) denotes the i-th number of authorized settlements H [j] of the number of provisional rules of procedure at the race management.

Sample input

10
2 1
3 2
4 3
5 4
6 1
7 3
8 3
9 4
10 1
5
2
6 1
5
2 7 3 6 9
1
8
4
8 7 10 3
5c
2 9 3 5 8

Sample Output

1 9
3 1 4 1 1
10
1 1 3 5
4 1 3 1 1

Resolve

First, we analyze the problem of model. There are a query q, each time a key point m, while the \ (\ sum {m [i ]} \) and relatively small, whereby we can think of a virtual tree. So as per provisional rules of procedure at the critical point, the establishment of a virtual tree.

After the virtual tree is set up, we will consider how dynamic programming on it. Virtual tree requires a point away from the nearest key point, obviously, from a critical point of closest key point is that it itself. Then for other points reserved, set \ (to [i] \) represents \ (i \) which governed point return, the trees move with the idea of regulation is clearly a point of \ (to \) value either by its son update (ie point son belongs to the distance from the point closer to or smaller numbers) or updated by its father. Thus, we can be divided into two dynamic programming, a father with his son to the update, the update time with father son. Depending on the update order, DFS successively different.

After that, we would require each jurisdiction at the number of points of procedure. Currently there is information known at the procedure of the virtual tree key point belongs, our next task is to get the information to other nodes in the tree with the information. To refresh the virtual tree construction principle, between two adjacent key points already contracted by a chain, we are now trying to recover out of this chain and statistical answer. For virtual tree two adjacent points (ab & \) \ link between, there must be a boundary point \ (C \) makes \ (C \) below the return point \ (to [b] \) Territories, more return \ (to [a] \) jurisdiction. Easy to think that this cutoff point must be \ (to [a] \) and \ (to [b] \) the midpoint between the (necessarily at the midpoint of course \ (A \) and \ (B \) between, otherwise \ (ab \) must belong to the same point). We can not directly one by one to find, you can use the method of multiplication. So how demand chain \ ((a, b) \ ) contributions between it? Set \ (A \) first son \ (X \) , since the procedure is not necessarily at the (virtual tree ......) chain, from \ (B \) to \ (C \) between point and its sub-tree are all \ (to [B] \) , the remaining part of \ (to [a] \). Expression is the formula with:
\ [F [to [A]] + = size [X] -size [C], F [to [B]] = + size [C] -size [B] \]
wherein \ ( f [i] \) represents \ (I \) number of nodes points jurisdiction, \ (size [I] \) represents the root node as \ (I \) subtree size.

As can be seen, the above process does not discuss the contribution of the virtual key tree produced. Special about these points is that they may be connected at the other procedure. For any virtual tree key point \ (U \) , not only at the sub-tree to the proceedings and (u \) \ point return with \ (to [u] \) jurisdiction. Thus, setting \ (rest [u] \) is initialized to \ (size [U] \) , in the above process, each find a key \ (A \) a \ (X \) , causes the \ (REST [A] - = size [X] \) , and finally separate the \ (REST \) accumulated added answer.

He talked about for so long, finally the code ----

Code

// luogu-judger-enable-o2
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define N 300002
using namespace std;
int head[N],ver[N*2],nxt[N*2],l;
int n,m,i,j,k,size[N],dep[N],fa[N][20],tim,dfn[N],x;
int a[N],tmp[N],to[N],s[N],t[N],top,cnt,rec[N],rest[N],f[N];
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
void insert(int x,int y)
{
    l++;
    ver[l]=y;
    nxt[l]=head[x];
    head[x]=l;
}
void dfs(int x,int pre)
{
    dfn[x]=++tim;fa[x][0]=pre;
    size[x]=1;dep[x]=dep[pre]+1;
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y!=pre){
            dfs(y,x);
            size[x]+=size[y];
        }
    }
}
void init()
{
    dfs(1,0);
    for(int j=0;(1<<(j+1))<n;j++){
        for(int i=1;i<=n;i++){
            if(fa[i][j]==0) fa[i][j+1]=0;
            else fa[i][j+1]=fa[fa[i][j]][j];
        }
    }
}
int LCA(int u,int v)
{
    if(dep[u]>dep[v]) swap(u,v);
    int tmp=dep[v]-dep[u];
    for(int i=0;(1<<i)<=tmp;i++){
        if(tmp&(1<<i)) v=fa[v][i];
    }
    if(u==v) return u;
    for(int i=(int)log2(1.0*n);i>=0;i--){
        if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
    }
    return fa[u][0];
}
int cmp(const int &x,const int &y)
{
    return dfn[x]<dfn[y];
}
int dis(int x,int y)
{
    return dep[x]+dep[y]-2*dep[LCA(x,y)];
}
void dfs1(int x)
{
    rec[++tim]=x;rest[x]=size[x];
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        dfs1(y);
        if(!to[y]) continue;
        int d1=dis(to[y],x),d2=dis(to[x],x);
        if(d1<d2||(d1==d2&&to[y]<to[x])||!to[x]) to[x]=to[y];
    }
}
void dfs2(int x)
{
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        int d1=dis(to[x],y),d2=dis(to[y],y);
        if(d1<d2||(d1==d2&&to[x]<to[y])||!to[y]) to[y]=to[x];
        dfs2(y);
    }
}
void dp(int a,int b)
{
    int x=b,mid=b;
    for(int i=18;i>=0;i--){
        if(dep[fa[x][i]]>dep[a]) x=fa[x][i];
    }
    rest[a]-=size[x];
    if(to[a]==to[b]){
        f[to[a]]+=size[x]-size[b];
        return;
    }
    for(int i=18;i>=0;i--){
        int nxt=fa[mid][i];
        if(dep[nxt]<=dep[a]) continue;
        int d1=dis(nxt,to[b]),d2=dis(nxt,to[a]);
        if(d1<d2||(d1==d2&&to[b]<to[a])) mid=nxt;
    }
    f[to[a]]+=size[x]-size[mid];
    f[to[b]]+=size[mid]-size[b];
}
int main()
{
    n=read();
    for(i=1;i<n;i++){
        int u,v;
        u=read();v=read();
        insert(u,v);insert(v,u);
    }
    init();
    m=read();
    for(i=1;i<=m;i++){
        memset(head,0,sizeof(head));
        memset(f,0,sizeof(f));
        memset(to,0,sizeof(to));
        memset(rest,0,sizeof(rest));
        tim=top=l=0;
        x=read();
        for(j=1;j<=x;j++){
            a[j]=read();
            to[a[j]]=tmp[j]=a[j];
        }
        sort(a+1,a+x+1,cmp);
        if(to[1]!=1) s[++top]=1;
        for(j=1;j<=x;j++){
            int lca=0;
            while(top){
                lca=LCA(a[j],s[top]);
                if(top>1&&dep[s[top-1]]>dep[lca]){
                    insert(s[top-1],s[top]);
                    top--;
                }
                else if(dep[s[top]]>dep[lca]){
                    insert(lca,s[top]);
                    top--;
                    break;
                }
                else break;
            }
            if(s[top]!=lca) s[++top]=lca;
            s[++top]=a[j];
        }
        while(top>1){
            insert(s[top-1],s[top]);
            top--;
        }
        dfs1(1);dfs2(1);
        for(j=1;j<=tim;j++){
            for(k=head[rec[j]];k;k=nxt[k]) dp(rec[j],ver[k]);
        }
        for(j=1;j<=tim;j++) f[to[rec[j]]]+=rest[rec[j]];
        for(j=1;j<=x;j++) printf("%d ",f[tmp[j]]);
        puts("");
    }
    return 0;
}
//P.S. 用轻重链剖分求LCA可以不用开O2。(O_O)

Guess you like

Origin www.cnblogs.com/LSlzf/p/10985732.html