CF1101D GCD Counting 点分治+质因数分解

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

#include  
#include  
#include  
#define N 200004  
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
int n,tot,edges,sn,root,tl,answer; 
vectorv[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]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;k1) 
            {
                for(int k=0;k1) for(int k=0;k1) for(j=0;j

  

转载于:https://www.cnblogs.com/guangheli/p/11477330.html

你可能感兴趣的:(CF1101D GCD Counting 点分治+质因数分解)