zoukankan      html  css  js  c++  java
  • CF1101D GCD Counting 点分治+质因数分解

    题意:求最长的树上路径点值的 $gcd$ 不为 $1$ 的长度.
    由于只要求 $gcd$ 不为一,所以只要 $gcd$ 是一个大于等于 $2$ 的质数的倍数就可以了.
    而我们发现 $2 imes 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
    ",answer);       
        return 0;    
    }         
    

      

  • 相关阅读:
    数据库基础理解学习-Mysql
    玫瑰花小制作分享-JavaScript(七夕专属浪漫)
    爬虫探索Chromedriver+Selenium初试
    Python 数据结构理解分享
    Python 实用第三方库安装方法
    Python安装-Pycharm+Anaconda
    oracle父子级查询数据树结构
    如何查看class文件的编译jdk版本号
    PL/SQL developer 11.0注册码
    linux 下tomcat出现 Native memory allocation (malloc) failed to allocate 1915224064 bytes for committing reserved memory问题
  • 原文地址:https://www.cnblogs.com/guangheli/p/11477330.html
Copyright © 2011-2022 走看看