hdu 5468 Puzzled Elena
一颗大小为(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相关推荐
- hdu 5468 Puzzled Elena(前缀性质+dfs序+容斥)
题目链接:hdu 5468 Puzzled Elena 解题思路 预处理出每个数的因子(注意只需要质因子幂数最大为1的数,例如6=21∗316=2^1 * 3^1)然后用一个数组维护,fac[i]表示 ...
- HDU 5468 Puzzled Elena(2015 ACM/ICPC Asia Regional Shanghai Online)
题目大意 这道题要求出每个节点与其子树节点中有多少个节点互质,题目是这样,但是如果你认为真的是这样那就错了,因为有可能根节点是1,那么1与本身也是互质的!!其实我真的搞不懂,说好了与子树互质为什么就把 ...
- HDU - 5468 Puzzled Elena —— 容斥
题意: 每个点的子树上有几个节点与该节点的权值互质 思路: 首先要明白怎么求一个集合中有多少个数与n互素 将集合中的数用算术基本定理分解,记录每个数能形成的所有因子的个数,然后将n分解进行容斥,可以求 ...
- HDU - 5468 Puzzled Elena (容斥/莫比乌斯)
做了好几个容斥了,一直找不到feel,这个做完在现在有一点感觉了.虽然刚开始也不会.但就是发现感觉不一样了. 首先,不考虑树的关系,单纯给出一个m,还有一个集合(里面数字任意),求集合里面跟m互质的数 ...
- HDU 5468 Puzzled Elena 莫比乌斯反演
题意: 给出一棵树,每个点上有权值.然后求每棵子树中与根节点互质( \(gcd(a, b) = 1\) )的节点个数. 分析: 对于一颗子树来说,设根节点的权值为\(u\), \(count_i\)表 ...
- 【HDU】5468 Puzzled Elena
Puzzled Elena 题目链接 Puzzled Elena 题目大意 给你一棵树,n个节点n-1条边,每个节点都有一个权值.现在让你求每个节点的子树下面有多少个节点与该节点互质. 题解 容斥原理 ...
- mobius HDOJ 5468 Puzzled Elena
dfs遍历树+莫比乌斯反演.. #include <bits/stdc++.h> using namespace std; typedef long long LL;const int m ...
- hdu5468 Puzzled Elena
hdu5468 Puzzled Elena 题意 求一棵子树内与它互质的点个数 解法 容斥 我们先求出与它不互质的数的个数,再用总数减去就好. #include <cstdio> #inc ...
- Puzzled Elena
Puzzled Elena . . 题意:给定一棵树,1为根节点,问每个节点的子树有多少个与他互质的数. . . 解法:DFS序加容斥原理(莫比乌斯),DFS时用一个全局数组记录,count[i] 表 ...
最新文章
- NYOJ——街区最短路径问题
- .NET :如何对数组进行排序
- 从终端运行React Native App时出错(iOS)
- 玩转Mixly – 6、Arduino AVR编程 之 文本
- CentOS 6.5 安装与配置LAMP
- Fragment(优化布局)
- oracle静默安装快吗,Oracle静默安装简要的注意事项
- Python: sorted() 函数
- python服务器搭建nginx_从0开始搭建nginx-uWSGI-Django-python服务器
- django-rest-framework-jwt的使用
- linux apt 安装命令
- 2018春招-今日头条笔试题-第四题(python)
- linux获取软电话信息,完整的SIP软电话工程实施过程
- 如何做一个简单的类似qq网页版等的聊天网页
- Linux 下搭建 Kafka 环境
- 一篇讲给自己听的k8s网络模型
- android国际化-判断国家
- ECharts 异步加载数据及loading 动画
- 【移动安全】专栏文章汇总
- 8Manage PM:通过项目管理信息系统做好进度管控
热门文章
- 图形推理1000题pdf_2021上海事业单位备考行测判断推理:图形推理之位置变化
- 代理模式-为别人做嫁衣
- 最新 GitHub 上传本地项目代码 (main) (2022 更新)
- java购买电视_以程序员的角度怎么购买一台「性价比高的电视」
- C#控制Excel的打印格式
- java小游戏龟兔赛跑,Java_多线程_简单模拟龟兔赛跑
- Linux 多进程(一)
- 直播预告 | 基于层级超图匹配的图相似度学习网络
- 普通html使用引入element-ui,图标出错
- 前端面试题高性能高并发100+