• HDU5468 Puzzled Elena


    题目很简单,但是想要写出比较优的复杂度需要基础比较扎实。

    题目

    给定一棵 (n) 个结点的有根树,点 (u) 有点权 (a_u)。求每个点 (u) 的子树内有多少点 (v) 满足 (a_u)(a_v) 互质。
    (1le nle 10^5,1le a_ule 10^5),多组数据,数据组数不超过 (8)

    即求 (sum_{v in subtree u} [gcd(a_u,a_v)=1])

    莫比乌斯反演得 (sum_{d|a_u}mu(d)sum_{v in subtree u} [d|a_v])

    也就是对 (a_u) 的每个约数 (d) 求子树里有多少 (d) 的倍数。

    DFS 序上树状数组差不多是 (O(max a_i+sum d(a_i)log n)) 的,可能就可以过了。

    我们采用一个经典套路:DFS 一遍树,对 (d) 开一个桶 (b[]),经过点 (u) 时把其所有约数塞进桶里。那么答案等于从 (u) 的子树出去时的 (sum_{d|a_u} mu(d)b[d]) 减去进来时的 (sum_{d|a_u} mu(d)b[d]) 。复杂度降到 (O(max a_i+sum d(a_i)))

    然后注意到只有分解质因数形如 (x=p_1p_2cdots p_k) 的数满足 (mu(x) e 0),而 (a) 的这样的约数只有 (2^{omega(a)}) 个。复杂度 (O(max a_i+sum 2^{omega(a_i)}))

    最后回顾一个质因数分解的好办法:线筛出每个数的最小质因数,然后一直除即可。

    #include<bits/stdc++.h>
    const int N=1e5+3,A=1e5+3,K=10;
    std::vector<int>g[N];
    int a[N],n,p[A],k,d[A],mu[A],s[N],t[A];
    bool np[A];
    void Dfs(int u,int fa){
        int v,b,q[K],c;
        c=0;
        for(b=a[u];b>1;b/=d[b])if(!c||q[c-1]!=d[b])q[c++]=d[b];
        for(int I=0;I<(1<<c);I++){
            b=1;for(int j=0;j<c;j++)if(I>>j&1)b*=q[j];
            s[u]-=mu[b]*t[b];
            ++t[b];
        }
        for(int i=0;i<g[u].size();i++)if((v=g[u][i])!=fa)Dfs(v,u);
        for(int I=0;I<(1<<c);I++){
            b=1;for(int j=0;j<c;j++)if(I>>j&1)b*=q[j];
            s[u]+=mu[b]*t[b];
        }
    }
    int main(){
        int u,v;
        mu[1]=1;
        for(int i=2;i<A;i++){
            if(!np[i])p[++k]=i,mu[i]=-1,d[i]=i;
            for(int j=1;j<=k&&i*p[j]<A;j++){
                np[i*p[j]]=1;
                if(i%p[j])mu[i*p[j]]=-mu[i],d[i*p[j]]=p[j];
                else{d[i*p[j]]=d[i];break;}
            }
        }
        for(int T=1;~scanf("%d",&n);T++){
        for(int i=0;i<A;i++)t[i]=0;
        for(u=1;u<=n;u++)g[u].clear(),s[u]=0;
        for(int i=1;i<n;i++)scanf("%d%d",&u,&v),g[u].push_back(v),g[v].push_back(u);
        for(u=1;u<=n;u++)scanf("%d",a+u);
        Dfs(1,0);
        printf("Case #%d:",T);for(u=1;u<=n;u++)printf(" %d",s[u]);puts("");
        }return 0;
    }
    
  • 相关阅读:
    [WWF]相关资料整理
    [CSharp]经常遇到字符编码转换的问题
    [BizTalk]BizTalk Server 2004的监控和管理
    [Linux]删除目录
    [BizTalk]好用的BizTalk管理工具
    [JWF]使用脚本访问ActiveDirectory(一)ADODB
    [BizTalk][Why]持久化数据库的状态时出现异常
    [BizTalk]关于BizTalk中的命名规则
    FTP连接
    [导入]跟踪BTSWebSvcWiz.exe的执行过程
  • 原文地址:https://www.cnblogs.com/Camp-Nou/p/15090371.html
Copyright © 2020-2023  润新知