hdu 6430 TeaTree 线段树合并

hdu 6430

多校十第五题,我是从丿残念灬这位大佬学的,从来没写过线段树合并,第一次发现还有这操作,学到了学到了,这个题求任意点 i 和以其为根的子树的所有点 j 的max( gcd  (v[ i ], v[ j ]) ),写法是建立n个线段树,每个线段树保存的是该点权值的所有因数,首先将1e5个数的所有因数打表,然后再将n个点的权值一一建线段树,复杂度应该是n*logn*logn,然后走dfs,从底部向上合并节点,每次都把儿子节点合并到父节点,所以每个点只被合并一次,合并的复杂度大概也是之前的数量级,在合并的过程中求出父节点的最大的gcd(fa,son),具体怎么合并,看代码更容易理解。

#include
#include
#include
#include
using namespace std;
const int maxn=1e5+10;
int rt[maxn],ls[maxn*400],rs[maxn*400],sum[maxn*400];
vectorG[maxn],fac[maxn];
int cnt=0,sz=1e5,ans[maxn];
void init()
{
	for(int i=1;i

 

你可能感兴趣的:(数据结构----线段树)