hdu6430树上启发式合并

题解:因为这题我们只查询不做修改,那么在树上做启发式合并就会很方便并且时间复杂度做到查询万每课子树最后的时间复杂度是nlogn就可以查询每个结点为根的子树信息,每次标记一下0表示信息不保留,1表示信息保留,找最大公约数,我们用一个标记数组把每个结点的因子都加一,因为因子个数最多100个所以时间复杂度是100nlogn,

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mes(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i = a; i <= b; i++)
#define dec(i,a,b) for(int i = a; i >= b; i--)
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define lson ls,L,mid
#define rson rs,mid+1,R
#define lowbit(x) x&(-x)
typedef double db;
typedef long long int ll;
typedef pair pii;
typedef complex cd;
typedef unsigned long long ull;
const ll inf = 0x3f3f3f3f;
const int mx = 1e5+5;
const int mod = 1e9+7;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
vectord[mx];
vectorg[mx];
int vis[mx];
int sz[mx];
int son[mx];
int st[mx];
int ed[mx];
int val[mx];
int id[mx];
int pos;
int ans[mx];
void init(){
	for(int i = 1; i < mx; i++)
		for(int j = i; j < mx; j+=i)
			d[j].pb(i);
	for(int i = 1; i < mx; i++)
		reverse(d[i].begin(),d[i].end());
}
void dfs(int u){
	sz[u]  = 1;
	son[u] = 0;
	pos++;
	st[id[pos] = u] = pos;
	for(auto v: g[u]){
		dfs(v);
		sz[u] += sz[v];
		if(sz[son[u]]

 

你可能感兴趣的:(启发式)