题意:求最长的树上路径点值的 $gcd$ 不为 $1$ 的长度.
由于只要求 $gcd$ 不为一,所以只要 $gcd$ 是一个大于等于 $2$ 的质数的倍数就可以了.
而我们发现 $2\times 10^5$ 以内的数最多只会有 $7$~$8$ 个本质不同的质因子,所以我们在点分治的时候暴力拆质因子并维护一些桶即可.

#include <cstdio>
#include <vector>
#include <algorithm>
#define N 200004
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,tot,edges,sn,root,tl,answer;
vector<int>v[N];
int prime[N],is[N],num[N];
int val[N],hd[N],to[N<<1],nex[N<<1];
int size[N],mx[N],vis[N],f[N],g[N],tmp[N],depth[N],cur[N],number[N];
void add(int u,int v)
{
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void getroot(int u,int ff)
{
size[u]=1,mx[u]=0;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
getroot(to[i],u),size[u]+=size[to[i]],mx[u]=max(mx[u],size[to[i]]);
mx[u]=max(mx[u],sn-size[u]);
if(mx[u]<mx[root]) root=u;
}
void dfs(int u,int ff,int dep)
{
number[u]=tmp[++tl]=__gcd(val[u],number[ff]),depth[tl]=dep;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff&&!vis[to[i]])
dfs(to[i],u,dep+1);
}
void calc(int u)
{
int i,j,re;
if(val[u]>1) answer=max(answer,1);
tl=0;
number[u]=val[u];
for(i=hd[u];i;i=nex[i])
{
if(vis[to[i]]) continue;
re=tl+1,dfs(to[i],u,1);
for(j=re;j<=tl;++j)
{
int a=tmp[j],b=depth[j];
if(a>1)
{
for(int k=0;k<v[a].size();++k)
g[v[a][k]]=max(g[v[a][k]],b),answer=max(answer,g[v[a][k]]+f[v[a][k]]+1);
}
}
for(j=re;j<=tl;++j)
{
int a=tmp[j];
if(a>1)
{
for(int k=0;k<v[a].size();++k) f[v[a][k]]=max(f[v[a][k]],g[v[a][k]]);
}
}
for(j=re;j<=tl;++j)
{
int a=tmp[j];
if(a>1) for(int k=0;k<v[a].size();++k) g[v[a][k]]=0;
}
}
for(i=1;i<=tl;++i)
{
int a=tmp[i];
if(a>1) for(j=0;j<v[a].size();++j) f[v[a][j]]=g[v[a][j]]=0;
}
}
void solve(int u)
{
vis[u]=1,calc(u);
for(int i=hd[u];i;i=nex[i])
if(!vis[to[i]])
sn=size[to[i]],root=0,getroot(to[i],u),solve(root);
}
void init()
{
int i,j;
for(i=2;i<N;++i)
{
if(!is[i]) prime[++tot]=i;
for(j=1;j<=tot&&i*prime[j]<N;++j)
{
is[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
for(i=2;i<N;++i) num[i]=i;
for(i=1;i<=tot;++i)
for(j=prime[i];j<N;j+=prime[i])
{
v[j].push_back(prime[i]);
while(num[j]%prime[i]==0) num[j]/=prime[i];
}
}
int main()
{
int i,j;
init();
// setIO("input");
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%d",&val[i]);
for(i=1;i<n;++i)
{
int a,b;
scanf("%d%d",&a,&b),add(a,b),add(b,a);
}
mx[root=0]=sn=n,getroot(1,0),solve(root);
printf("%d\n",answer);
return 0;
}

  

CF1101D GCD Counting 点分治+质因数分解的更多相关文章

  1. CF1101D GCD Counting

    题目地址:CF1101D GCD Counting zz的我比赛时以为是树剖或者点分治然后果断放弃了 这道题不能顺着做,而应该从答案入手反着想 由于一个数的质因子实在太少了,因此首先找到每个点的点权的 ...

  2. CF1101D GCD Counting(数学,树的直径)

    几个月的坑终于补了…… 题目链接:CF原网  洛谷 题目大意:一棵 $n$ 个点的树,每个点有点权 $a_i$.一条路径的长度定义为该路径经过的点数.一条路径的权值定义为该路径经过所有点的点权的 GC ...

  3. BZOJ-1705 Longge的问题 一维GCD SUM 乱搞+质因数分解+...

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec Memory Limit: 128 MB Submit: 1871 Solved: 1172 [Submit][ ...

  4. CF990G GCD Counting 点分治+容斥+暴力

    只想出来 $O(nlogn\times 160)$ 的复杂度,没想到还能过~ Code: #include <cstdio> #include <vector> #includ ...

  5. algorithm@ 大素数判定和大整数质因数分解

    #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #in ...

  6. 质因数分解的rho以及miller-rabin

    一.前言 质因数分解,是一个在算法竞赛里老生常谈的经典问题.我们在解决许多问题的时候需要用到质因数分解来辅助运算,而且质因数分解牵扯到许许多多经典高效的算法,例如miller-rabin判断素数算法, ...

  7. Vijos P1786 质因数分解【暴力】

    质因数分解 背景 NOIP2012普及组第一题 描述 已知正整数n是两个不同的质数的乘积试求出较大的那个质数. 格式 输入格式 输入只有一行包含一个正整数n. 输出格式 输出只有一行包含一个正整数p, ...

  8. CF1139D Steps to One(DP,莫比乌斯反演,质因数分解)

    stm这是div2的D题……我要对不住我这个紫名了…… 题目链接:CF原网  洛谷 题目大意:有个一开始为空的序列.每次操作会往序列最后加一个 $1$ 到 $m$ 的随机整数.当整个序列的 $\gcd ...

  9. [学习笔记] Miller-Rabin质数测试 & Pollard-Rho质因数分解

    目录 Miller-Rabin质数测试 & Pollard-Rho质因数分解 Miller-Rabin质数测试 一些依赖的定理 实现以及正确率 Pollard-Rho质因数分解 生日悖论与生日 ...

随机推荐

  1. BUUOJ reverse SimpleRev (爆破)

    SimpleRev SimpleRev(flag需加上flag{}再提交) 注意:得到的 flag 请包上 flag{} 提交 拖到ida 找到关键函数: unsigned __int64 Decry ...

  2. Partition to K Equal Sum Subsets

    Given an array of integers nums and a positive integer k, find whether it's possible to divide this ...

  3. selenium Grid2环境搭建和基本使用

    Selenium Grid简介 利用Selenium Grid可以使主节点(hub)的测试用例在不同主机即分支点(node)运行.可以使一份测试用例在不同环境下(操作系统.浏览器)执行自动化测试.Se ...

  4. Linux运维必备工具

    1. 查看进程占用带宽情况 - Nethogs Nethogs 是一个终端下的网络流量监控工具可以直观的显示每个进程占用的带宽. 前提条件:安装c++环境 yum install -y gcc-c++ ...

  5. 多进程-Pool进程池

    from multiprocessing import Pool import os,time def Foo(i): time.sleep(2) print("in process&quo ...

  6. Leetcode简单题

    # Title Solution Acceptance Difficulty Frequency     1 Two Sum       44.5% Easy     2 Add Two Number ...

  7. WPF ListView多行显示

    //前台 <ListView Margin="14,152,12,74" Name="lvList" SelectionMode="Multip ...

  8. Mysql学习(二)之安装、开启自启、启动、重启、停止

    安装 方法一:通过homebrew brew install mysql 方法二:通过官网dmg文件安装(Mac) https://dev.mysql.com/downloads/mysql/ 通过h ...

  9. 07 Python之协程

    协程: 协程是一种用户态的轻量级线程, 即协程是由用户程序自己控制调度的 1.Greenlet import time # import greenlet from greenlet import g ...

  10. Vue开发——实现吸顶效果

    因为项目需求,最近开始转到微信公众号开发,接触到了Vue框架,这个效果的实现虽说是基于Vue框架下实现的,但是同样也可以借鉴到其他地方,原理都是一样的. 进入正题,先看下效果图: 其实js做这个效果还 ...