C. Ilya y el árbol (análisis gcd de la transferencia de la violencia +)

título

Significado de las preguntas:

    Dado un árbol, cada punto tiene los valores correctos. gcd respuesta correcta a todos los puntos en cada nodo para el nodo raíz igual al valor de la ruta, para cada punto, de peso puede hacer un punto sobre este valor de ruta se convierte en 0, la respuesta requiere que cada nodo lo más grande posible.
     1 norte 2 1 0 5 , 1 yo norte , 1 una i 2 1 0 5 1 ≤ n ≤ 2 · 10 ^ 5,1 ≤ i ≤ n, 1 ≤ a_i ≤ 2 · 10 ^ 5

análisis:

    Debido mcd, mcd es una naturaleza muy evidente de este tipo de valores no son muchos, el punto clave de esta pregunta aquí. Por lo que podemos calcular la violencia que, para cada punto para mantener un conjunto, después del depósito del nodo actual para eliminar un punto de la ruta raíz del resto del mcd. Cuando se busca el mantenimiento de este conjunto sobre el mismo, para el nodo actual, fue tomada con los números correctos para el valor del nodo actual tiene mcd se puede ajustar de una serie de nodos padre, ya que sólo elimina una vez, además de la eliminación del nodo actual mcd puede ser, este mcd recursiva cuando el siguiente pase.

#include <iostream>
#include <vector>
#include <set> 
using namespace std;

vector<int> g[200005];
set<int> res[200005];
int dp[200005][2],v[200005];

int _gcd(int a,int b)
{
	if( b == 0 ) return a;
	return _gcd(b,a%b);
} 

void dfs(int x,int fa,int gcd)
{
	for (int i = 0; i < g[x].size(); i++)
	{
		int t = g[x][i];
		if( t == fa ) continue;
		set<int>:: iterator it;
		res[t].insert(gcd);
		for (it = res[x].begin(); it != res[x].end(); it++)
		{
			res[t].insert(_gcd(*it,v[t]));
		}
		dfs(t,x,_gcd(gcd,v[t]));
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> v[i];
	}
	for (int i = 1; i < n; i++)
	{
		int x,y;
		cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);  
	}
	dp[1][0] = v[1];
	dp[1][1] = 0;
	res[1].insert(0);
	dfs(1,0,v[1]);
	for (int i = 1; i <= n; i++)
	{
		if( i == 1 ) cout << v[i];
		else cout << *--res[i].end();
		if( i == n ) cout << '\n';
		else cout << ' ';
	}
	return 0;
}

Publicados 132 artículos originales · ganado elogios 6 · vistas 7908

Supongo que te gusta

Origin blog.csdn.net/weixin_44316314/article/details/105137331
Recomendado
Clasificación