2015上海网络赛 A Puzzled Elena
题意:给定一棵树,求这个节点的所有子树中包括他本身与它互质的节点的个数.
解题思路:题利用dfs序+容斥原理+前缀和性质解决。题目中要求每个结点,和多少个它的子结点互素。如果每次为了求一个点去跑一遍dfs,复杂度将是 O(N(N+M))。一定会超时。因此需要深入加以分析。注意到n的范围是10^5以内的,因此可以事先用线性筛求出每个数含有哪些素因子。接下来,我们 尝试利用dfs序来求解。设num[i]表示遍历到当前结点时候,含有因数i(注意,不一定是素数)的结点个数。可以发现,如果第一次遍历到结点u,含有 u的因数的个数为a,那么第二次遍历到u时候,含有u的因数的个数变成了b,那么b-a就是u的子树中,含有u的因数的结点个数,即和u不互素的结点个 数。用总的结点数减掉这部分,即得到了和u互素的结点个数。这正是用了前缀和的性质。那么,如何求解有当前有多个结点含有u的因数呢?可以利用容斥原理求解。因为我们已经预处理出来了所有数的素因数,假设有len个素因数,由于“含 有”即表示只要有1个即可。因此结果就是{只含有1种素因子的个数}-{只含有2种素因子的个数}+{只含有3个素因子的个数}-...+ (-1)^(n-1){含有n个素因子的个数}。这恰好就是容斥原理。至此,问题得以解决。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 #include<memory.h> 7 #include<cstdlib> 8 #include<vector> 9 #define clc(a,b) memset(a,b,sizeof(a)) 10 #define LL long long int 11 using namespace std; 12 const int N=100010; 13 const double eps=1e-8; 14 const int inf=0x3f3f3f3f; 15 16 int n; 17 int val[N]; 18 int ans[N]; 19 int e; 20 int num[N]; 21 int head[N]; 22 vector<int>g[N]; 23 struct Edge 24 { 25 int to,next; 26 }edge[N*2]; 27 28 void add(int u,int v) 29 { 30 edge[e].to=v; 31 edge[e].next=head[u]; 32 head[u]=e++; 33 } 34 35 void init() 36 { 37 for(int i=2;i<N;i++) 38 { 39 if(!g[i].empty()) 40 continue; 41 for(int j=i;j<N;j+=i) 42 g[j].push_back(i); 43 } 44 } 45 46 int calc(int x,int y)//*y=0表示进入这颗树的时候,含有互质的数目为0;y=1表示dfs回溯的时候离开这棵树相应互质节点数目加一*// 47 { 48 int len=g[x].size(); 49 int res=0; 50 for(int i=1;i<(1<<len);i++) 51 { 52 int t=1; 53 int cnt=0; 54 for(int j=0;j<len;j++) 55 { 56 if(i&(1<<j)) 57 { 58 cnt++; 59 t=t*g[x][j]; 60 } 61 } 62 if(cnt%2) 63 res+=num[t]; 64 else 65 res-=num[t]; 66 num[t]+=y; 67 } 68 return res; 69 } 70 int dfs(int u,int pre) 71 { 72 int cnt=0; 73 int L=calc(val[u],0); 74 for(int i=head[u];~i;i=edge[i].next) 75 { 76 int v=edge[i].to; 77 if(v==pre) 78 continue; 79 cnt+=dfs(v,u); 80 } 81 int R=calc(val[u],1); 82 ans[u]=cnt-(R-L); 83 if(val[u]==1) 84 ans[u]++; 85 return cnt+1; 86 } 87 int main() 88 { 89 int u,v; 90 int cas=1; 91 while(~scanf("%d",&n)) 92 { 93 e=0; 94 init(); 95 clc(num,0); 96 clc(head,-1); 97 for(int i=0;i<n-1;i++) 98 { 99 scanf("%d%d",&u,&v); 100 add(u,v); 101 add(v,u); 102 } 103 for(int i=1;i<=n;i++) 104 { 105 scanf("%d",&val[i]); 106 } 107 dfs(1,0); 108 printf("Case #%d:",cas++); 109 for(int i=1;i<=n;i++) 110 { 111 printf(" %d",ans[i]); 112 } 113 printf("\n"); 114 } 115 return 0; 116 }
View Code
转载于:https://www.cnblogs.com/ITUPC/p/4867364.html
2015上海网络赛 A Puzzled Elena相关推荐
- 2019 ACM - ICPC 上海网络赛 E. Counting Sequences II (指数型生成函数)
繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...
- 树形DP+并查集+左偏树, HDU-5575,Discover Water Tank,2015上海现场赛D题
只是ACM/IICPC 2015 上海区域赛的一道题.原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5575 题目描述 N-1个木板把一个水箱划分成了N ...
- 2015长春网络赛 —— B. Ponds (拓扑排序删点+DFS)
题目描述 Description Betty owns a lot of ponds, some of them are connected with other ponds by pipes, an ...
- hdu5489(2015合肥网络赛F题)
转载自:http://blog.csdn.net/lwt36/article/details/48774103 题意: 给出一个数列,在其中删除连续的L个数字,使得剩余的数字LIS最大,输出此LIS. ...
- hdu5491(2015合肥网络赛H题)
题意: 给出三个数字D.s1和s2,用L来表示D的二进制表示中1的个数,L在区间[s1,s2]中,我们要找到离D最近的并且大于D的一个数字,且这个数字的L也落在区间[s1,s2]中. 思路: 一直超时 ...
- hdu5492(2015合肥网络赛I题)
题意: n*m的格子,每个格子有权值,我们要从左上角走到右下角,只能向下走或者向右走,求走到终点走过的格子的方差的最小值. 思路: 被这题坑了,我还是太蠢. 我们可以暴力(∑Ai)^2,取最优就好了. ...
- hihoCoder1233(2015北京网络赛H题)
转载自:http://blog.csdn.net/queuelovestack/article/details/48625899 题意: 有n个卡槽,放有体积不同的n个空盒子,每次你可以移动一个空盒子 ...
- hihoCoder1228(2015北京网络赛B题)
题意: 给出一个文本编辑器的容量,给出老板输入的字符串,小写字母代表文本,大写字母代表命令: L:光标左移: R:光标右移: S:在insert模式和另一个输入模式中切换: D:删除光标后面的一个字符 ...
- hdu5461(2015沈阳网络赛L题)
题意: 给出一个数列,我们要在这里找出两个数,使得题意中那个表达式最大. 思路: 排两个序就好了啊,看代码一下就懂了. 代码: #include <cstdio> #include < ...
最新文章
- python零基础怎么学-编程零基础应当如何开始学习 Python?
- PPT 图片python处理
- AOP开发——在不修改源代码的前提下,对类里面的方法进行增强 : 前置 后置 环绕 异常||如何得到目标方法的参数和返回值
- Orace 11g 监听 配置修改 说明
- .net 把一个对象赋值给一个参数_Java:new一个对象的过程中发生了什么?
- 转: Div与table的区别
- Spring Boot 多数据源(读写分离)入门
- xcode 工程没有模拟器_Xcode只允许我运行iOS设备(没有模拟器)
- 2021年中国以太网转换器市场趋势报告、技术动态创新及2027年市场预测
- EntityModelStudio系列教程
- 通过v$sqlarea,v$sql查询最占用资源的查询
- SVN回滚代码时,提示冲突怎么办
- Java实现冒泡排序算法
- JAVA高端编程研发培训班 JAVA开发视频教程
- 参考文献引用格式实例
- Java 工程师修炼之道
- 电信中兴f452光猫路由改桥接最简单的方式,亲自体验成功。
- 哪些行业申请网站备案时需要提供前置或专项审批文件?
- 获取汉字的拼音码(工具类)
- 贪心算法之田忌赛马(超详细)