小H和游戏

题目链接:https://ac.nowcoder.com/acm/contest/5203/D

想法:

最简单暴力的想法就是对于每一个点我们就让他以及和他距离为2的点权++

但是如果一个点有多个孩子就会 TLE

我们还一个考虑,一个点的点权受到 它自己 它的孩子 它的父亲 它的父亲的父亲影响,那么我们会发现其实我们只需要标记该点自己和它的父亲和它的父亲的父亲就可以了

#pragma GCC optimize(3,"Ofast","inline")//O3优化
#pragma GCC optimize(2)//O2优化
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <ctime>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>

#define LL long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)

const double eps = 1e-10;
const int maxn = 8e5 + 10;
const int mod = 10;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

vector<int> G[maxn];
int fa[maxn];
int f[maxn][3];

void dfs(int x) {
    for (int i = 0;i < G[x].size();i++) {
        int v = G[x][i];
        if (v == x || v == fa[x])
            continue;
        fa[v] = x;
        dfs(v);
    }
}

LL cal(int x) {
    LL sum = f[x][0] + f[x][1] + f[x][2];  // 孩子的影响
    if (fa[x]) { 
        sum = sum + f[fa[x]][2]; // 父亲自身的影响 
        sum = sum + f[fa[x]][1] - f[x][2]; // 兄弟的影响
    }
    if (fa[fa[x]]) {  // 父亲的父亲的影响
        sum = sum + f[fa[fa[x]]][2];
    }
    return sum;
}

int main() {
    ios::sync_with_stdio(false);
    int n,q;
    cin >> n >> q;
    for (int i = 1;i < n;i++) {
        int u,v;
        cin >> u >> v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    dfs(1);
    while (q--) {
        int x;
        cin >> x;
        f[x][2]++;
        if (fa[x]) {
            f[fa[x]][1]++;
        }
        if (fa[fa[x]])
            f[fa[fa[x]]][0]++;
        cout << cal(x) << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-Ackerman/p/12818435.html