Wannafly挑战赛10C 小H和游戏 ( Tree

C 小H和游戏

题目描述

小H正在玩一个战略类游戏,她可以操纵己方的飞机对敌国的N座城市(编号为1~N)进行轰炸
敌国的城市形成了一棵树,小H会依次进行Q次轰炸,每次会选择一个城市A进行轰炸,和这座城市距离不超过2的城市都会受损(这里距离的定义是两点最短路径上的边数),轰炸结束后,小H还想知道当前城市A受损的次数
作为游戏的开发者之一,你有义务回答小H的问题

输入

第1行,两个整数N(1≤N≤750000)、Q(1≤Q≤750000)
第2~N行,每行两个整数表示树上的一条边
第N+1~N+Q行,每行一个整数,表示小H这次轰炸的城市

输出

输出Q行,每行一个整数表示这一次轰炸的城市在此次轰炸后共计受损几次

样例

输入

4 4 
1 2 
2 3 
3 4 
1 
2 
3 
4
输出

1 
2 
3 
3

题意

离线查询问题就是防止重复计算贡献
设置一个数组计算点x对他的的子节点与孙节点的影响
( 输入量很大要常数优化下

AC代码

#include 
using namespace std;

#define CLR(a,b) memset(a,(b),sizeof(a))
#define LL long long


const int INF = 0x3f3f3f3f;
const int MAXN = 1e6+10;
const int mod = 19260817;
int sum[MAXN][3];
int  fa[MAXN];

vector<int> G[MAXN];
long long read()
{
    long long res = 0;
    char ch = 0;
    while (ch < '0' || ch > '9')
        ch = getchar();
    while (ch >= '0' && ch <= '9')
    {
        res = res * 10 + ch - '0';
        ch = getchar();
    }
    return res;
}
void dfs(int u, int f)
{
     fa[u] = f;
     for(int i = 0; i < (int)G[u].size(); i++) {
        int v = G[u][i];
        if(v == f) continue;
        dfs(v,u);
     }
}

int main()
{
    int n, q;
    cin >> n >> q;
    for(int i = 0; i < n-1; i++) {
        int u, v;
        u = read(), v = read();
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1,0);
    while(q--) {
        int x;
        x = read();
        sum[x][1]++, sum[x][2]++;
        sum[fa[x]][0]++; sum[fa[x]][1]++;
        sum[fa[fa[x]]][0]++;
        cout << sum[x][0]+sum[fa[x]][1]+sum[fa[fa[x]]][2] << endl;
    }
    return 0;
}

你可能感兴趣的:(online,judge,NOW,数据结构,其他树)