Codeforces 842 C Ilya And The Tree

来源:互联网 发布:电脑磁盘清理软件 编辑:程序博客网 时间:2024/06/06 20:08

题目地址
题意:给出一棵生成树,每个节点都有一个值,现在要求出每个节点的美丽值的最大值,美丽值的定义为从根节点到该节点(包含)路径上所有点的值的gcd,求解每个点时可以把路径上某一个点的值变为0(就相当于删除这个节点的数)。你可以认为每个点美丽值的求解是独立的(每次删除的点都不会影响下一次)。
思路:在这个树上进行dfs,然后我们边记录结果,在dp数组中记录的是到这个点的这条路径中一个节点都不删的美丽值,然而vector中记录的是删除了一个节点的全部情况,第一个就是删除看当前节点(因为他的值是上一个节点的dp数组中的值),然后就是上一个节点的vector中的值与当前节点的值得gcd(因为这个记录的是原来已经删除了一个节点的gcd现在更新一下),最后每个节点取最大值就好了。

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 200010#define M 400010#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;const int L = 200;struct node {    int to, next;}edge[M];int head[N], cnt, num[N], dp[N], n;//dp存的是没有删除数的结果,v中存储删除数的结果vector<int> v[N];void init() {    for (int i = 0; i <= n; i++) {        v[i].clear();    }    cnt = 0;    memset(head, -1, sizeof(head));}void add(int a, int b) {    edge[cnt].to = b;    edge[cnt].next = head[a];    head[a] = cnt++;    edge[cnt].to = a;    edge[cnt].next = head[b];    head[b] = cnt++;}int gcd(int a, int b) {    return b ? gcd(b, a%b) : a;}void dfs(int u, int pre) {    for (int i = head[u]; i != -1; i = edge[i].next) {        int to = edge[i].to;        if (to == pre) {            continue;        }        dp[to] = gcd(dp[u], num[to]);        v[to].push_back(dp[u]);        for (int i = 0; i < v[u].size(); i++) {            v[to].push_back(gcd(v[u][i], num[to]));        }        sort(v[to].begin(), v[to].end());        v[to].erase(unique(v[to].begin(), v[to].end()), v[to].end());        dfs(to, u);    }}int main() {    cin.sync_with_stdio(false);    int a, b;    while (cin >> n) {        init();        for (int i = 1; i <= n; i++) {            cin >> num[i];        }        for (int i = 1; i < n; i++) {            cin >> a >> b;            add(a, b);        }        dp[1] = num[1];        v[1].push_back(0);        dfs(1, -1);        for (int i = 1; i <= n; i++) {            dp[i] = max(dp[i], v[i].back());        }        for (int i = 1; i < n; i++) {            cout << dp[i] << " ";        }        cout << dp[n] << endl;    }    return 0;}
原创粉丝点击