一颗大小为(n<=100000) 的树,根为1,每个节点有个权值。问:每个节点 和 以这个节点为根的子树中 有多少权值和根的权值互质。

做法,我们首先要明白一个东西,就是当你已经知道了k个数,并且求出来了每个数的素因子,如何很快的求出第k+1个数,有多少个和前k个数互质。

这个做法可以容斥做,也可以用莫比乌斯反演,莫比乌斯反演要更快些。

因为每个数的大小<=100000 这个范围内   2*3*5*7*11*13 *17> 100000 最多只有 6 个素因子。

当我们知道这个怎么处理以后,我们可以利用dfs序,解决这个问题

我们求当前这个节点的答案时,用容斥搞就是:以这个节点为根的树的大小 - 有1个素因子和他相同的节点个数 + 有2个素因子和他相同的个数 - 有3个素因子和他相同的个数 ....

那么问题来了,我们如何求出有多少个 有1个素因子和他相同的个数,有2个素因子和他相同的个数 ,,,,,

我们维护一个数a[]数组,a[i] 代表包含因子为i 的节点个数。

那么在这颗树中,进入这颗树之前求一下(有1个素因子和他相同的节点个数,有2个素因子和他相同的节点个数.....),离开这颗树的时候再求一下(有1个素因子和他相同的节点个数,有2个素因子和他相同的节点个数.....),他们的差便是我们需要的(子树中的和他有关系的信息)。

到这里,问题就解决了,容斥版的做法 时间复杂度 O(n*2^6 + nlogn) :

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100000 + 1000;
int prim[maxn],cnt;
bool vis[maxn];
vector<int>F[maxn];
void get_prim()
{memset(vis,0,sizeof(vis)); cnt = 0;for(int i=0;i<maxn;i++) F[i].clear();for(int i=2;i<maxn;i++)if(!vis[i]){prim[cnt++] = i;for(int j=i;j<maxn;j+=i){F[j].push_back(i);vis[j] = 1;}}
}
int a[maxn];
int ans[maxn],val[maxn];
vector<int>G[maxn];
vector<int>factor;
int fatcnt;
void getFactor(int value){factor = F[value];fatcnt = factor.size();
}
void add(int x)
{getFactor(val[x]);int all = (1ll<<fatcnt);for(int i=1;i<all;i++){int tmp = 1;for(int j=0;j<fatcnt;j++) if( i&(1ll<<j) ){tmp *= factor[j];}a[tmp] ++ ;}
}
int dfs_clock;
int st[maxn],ed[maxn];
void dfs(int x,int fa)
{int fuck[100];st[x] = ++dfs_clock;getFactor(val[x]);int all = (1ll<<fatcnt);for(int i=1;i<all;i++){int tmp = 1;for(int j=0;j<fatcnt;j++) if( i&(1ll<<j) ){tmp *= factor[j];}fuck[i] = a[tmp] ;}for(int i=0;i<G[x].size();i++){int v = G[x][i];if(v == fa) continue;dfs(v,x);}ed[x] = dfs_clock;getFactor(val[x]);all = (1ll<<fatcnt);ans[x] = ed[x] - st[x];for(int i=1;i<all;i++){int tmp = 1,cnt=0;for(int j=0;j<fatcnt;j++) if( i&(1ll<<j) ){tmp *= factor[j];cnt++;}if(cnt & 1){ans[x] -= (a[tmp] - fuck[i]);}else{ans[x] += (a[tmp] - fuck[i]);}}add(x);if(val[x] == 1) ans[x]++;
}
int main()
{get_prim();int n,cas=0;while(~scanf("%d",&n)){for(int i=1;i<=n;i++) G[i].clear();for(int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);G[x].push_back(y);G[y].push_back(x);}for(int i=1;i<=n;i++) scanf("%d",&val[i]);memset(a,0,sizeof(a));dfs_clock = 0;dfs(1,-1);printf("Case #%d:",++cas);for(int i=1;i<=n;i++){printf(" %d",ans[i]);}puts("");}return 0;
}


hdu 5468 Puzzled Elena相关推荐

  1. hdu 5468 Puzzled Elena(前缀性质+dfs序+容斥)

    题目链接:hdu 5468 Puzzled Elena 解题思路 预处理出每个数的因子(注意只需要质因子幂数最大为1的数,例如6=21∗316=2^1 * 3^1)然后用一个数组维护,fac[i]表示 ...

  2. HDU 5468 Puzzled Elena(2015 ACM/ICPC Asia Regional Shanghai Online)

    题目大意 这道题要求出每个节点与其子树节点中有多少个节点互质,题目是这样,但是如果你认为真的是这样那就错了,因为有可能根节点是1,那么1与本身也是互质的!!其实我真的搞不懂,说好了与子树互质为什么就把 ...

  3. HDU - 5468 Puzzled Elena —— 容斥

    题意: 每个点的子树上有几个节点与该节点的权值互质 思路: 首先要明白怎么求一个集合中有多少个数与n互素 将集合中的数用算术基本定理分解,记录每个数能形成的所有因子的个数,然后将n分解进行容斥,可以求 ...

  4. HDU - 5468 Puzzled Elena (容斥/莫比乌斯)

    做了好几个容斥了,一直找不到feel,这个做完在现在有一点感觉了.虽然刚开始也不会.但就是发现感觉不一样了. 首先,不考虑树的关系,单纯给出一个m,还有一个集合(里面数字任意),求集合里面跟m互质的数 ...

  5. HDU 5468 Puzzled Elena 莫比乌斯反演

    题意: 给出一棵树,每个点上有权值.然后求每棵子树中与根节点互质( \(gcd(a, b) = 1\) )的节点个数. 分析: 对于一颗子树来说,设根节点的权值为\(u\), \(count_i\)表 ...

  6. 【HDU】5468 Puzzled Elena

    Puzzled Elena 题目链接 Puzzled Elena 题目大意 给你一棵树,n个节点n-1条边,每个节点都有一个权值.现在让你求每个节点的子树下面有多少个节点与该节点互质. 题解 容斥原理 ...

  7. mobius HDOJ 5468 Puzzled Elena

    dfs遍历树+莫比乌斯反演.. #include <bits/stdc++.h> using namespace std; typedef long long LL;const int m ...

  8. hdu5468 Puzzled Elena

    hdu5468 Puzzled Elena 题意 求一棵子树内与它互质的点个数 解法 容斥 我们先求出与它不互质的数的个数,再用总数减去就好. #include <cstdio> #inc ...

  9. Puzzled Elena

    Puzzled Elena . . 题意:给定一棵树,1为根节点,问每个节点的子树有多少个与他互质的数. . . 解法:DFS序加容斥原理(莫比乌斯),DFS时用一个全局数组记录,count[i] 表 ...

最新文章

  1. NYOJ——街区最短路径问题
  2. .NET :如何对数组进行排序
  3. 从终端运行React Native App时出错(iOS)
  4. 玩转Mixly – 6、Arduino AVR编程 之 文本
  5. CentOS 6.5 安装与配置LAMP
  6. Fragment(优化布局)
  7. oracle静默安装快吗,Oracle静默安装简要的注意事项
  8. Python: sorted() 函数
  9. python服务器搭建nginx_从0开始搭建nginx-uWSGI-Django-python服务器
  10. django-rest-framework-jwt的使用
  11. linux apt 安装命令
  12. 2018春招-今日头条笔试题-第四题(python)
  13. linux获取软电话信息,完整的SIP软电话工程实施过程
  14. 如何做一个简单的类似qq网页版等的聊天网页
  15. Linux 下搭建 Kafka 环境
  16. 一篇讲给自己听的k8s网络模型
  17. android国际化-判断国家
  18. ECharts 异步加载数据及loading 动画
  19. 【移动安全】专栏文章汇总
  20. 8Manage PM:通过项目管理信息系统做好进度管控

热门文章

  1. 图形推理1000题pdf_2021上海事业单位备考行测判断推理:图形推理之位置变化
  2. 代理模式-为别人做嫁衣
  3. 最新 GitHub 上传本地项目代码 (main) (2022 更新)
  4. java购买电视_以程序员的角度怎么购买一台「性价比高的电视」
  5. C#控制Excel的打印格式
  6. java小游戏龟兔赛跑,Java_多线程_简单模拟龟兔赛跑
  7. Linux 多进程(一)
  8. 直播预告 | 基于层级超图匹配的图相似度学习网络
  9. 普通html使用引入element-ui,图标出错
  10. 前端面试题高性能高并发100+