HDU - 5977

题意:

  给定一颗树,问树上有多少节点对,节点对间包括了所有K种苹果。

思路:

  点分治,对于每个节点记录从根节点到这个节点包含的所有情况,类似状压,因为K《=10。然后处理每个重根连着的点的值:直接枚举每个点,然后找出这个点对应的每个子集,累计和子集互补的个数。

  枚举一个数的子集,例如1010,它的子集包括1010,1000,0010,0000.这里有个技巧:

  1.     for(int s = x; s; s = (s - ) & x){
  2. res += 1ll*cnt[((<<k)-) ^ s];
  3. }
  1. //#pragma GCC optimize(3)
  2. //#pragma comment(linker, "/STACK:102400000,102400000") //c++
  3. // #pragma GCC diagnostic error "-std=c++11"
  4. // #pragma comment(linker, "/stack:200000000")
  5. // #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  6.  
  7. #include <algorithm>
  8. #include <iterator>
  9. #include <iostream>
  10. #include <cstring>
  11. #include <cstdlib>
  12. #include <iomanip>
  13. #include <bitset>
  14. #include <cctype>
  15. #include <cstdio>
  16. #include <string>
  17. #include <vector>
  18. #include <stack>
  19. #include <cmath>
  20. #include <queue>
  21. #include <list>
  22. #include <map>
  23. #include <set>
  24. #include <cassert>
  25.  
  26. using namespace std;
  27. #define lson (l , mid , rt << 1)
  28. #define rson (mid + 1 , r , rt << 1 | 1)
  29. #define debug(x) cerr << #x << " = " << x << "\n";
  30. #define pb push_back
  31. #define pq priority_queue
  32.  
  33. typedef long long ll;
  34. typedef unsigned long long ull;
  35. //typedef __int128 bll;
  36. typedef pair<ll ,ll > pll;
  37. typedef pair<int ,int > pii;
  38. typedef pair<int,pii> p3;
  39.  
  40. //priority_queue<int> q;//这是一个大根堆q
  41. //priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
  42. #define fi first
  43. #define se second
  44. //#define endl '\n'
  45.  
  46. #define OKC ios::sync_with_stdio(false);cin.tie(0)
  47. #define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
  48. #define REP(i , j , k) for(int i = j ; i < k ; ++i)
  49. #define max3(a,b,c) max(max(a,b), c);
  50. #define min3(a,b,c) min(min(a,b), c);
  51. //priority_queue<int ,vector<int>, greater<int> >que;
  52.  
  53. const ll mos = 0x7FFFFFFF; //
  54. const ll nmos = 0x80000000; //-2147483648
  55. const int inf = 0x3f3f3f3f;
  56. const ll inff = 0x3f3f3f3f3f3f3f3f; //
  57. const int mod = 1e9+;
  58. const double esp = 1e-;
  59. const double PI=acos(-1.0);
  60. const double PHI=0.61803399; //黄金分割点
  61. const double tPHI=0.38196601;
  62.  
  63. template<typename T>
  64. inline T read(T&x){
  65. x=;int f=;char ch=getchar();
  66. while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
  67. while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
  68. return x=f?-x:x;
  69. }
  70.  
  71. /*-----------------------showtime----------------------*/
  72.  
  73. const int maxn = ;
  74. int a[maxn],g[maxn],dp[maxn],cnt[maxn];
  75. vector<int>mp[maxn];
  76. int n,k;
  77. ll ans = ;
  78.  
  79. void dfs(int u,int fa){
  80. dp[u] = ;
  81. for(int i=; i<mp[u].size(); i++){
  82. int v = mp[u][i];
  83. if(g[v] || fa == v)continue;
  84. dfs(v, u);
  85. dp[u] += dp[v];
  86. }
  87. }
  88. pii findg(int u,int fa, int sz){
  89. int mx = ;
  90. pii tmp = pii(inf, u);
  91.  
  92. for(int i=; i<mp[u].size(); i++){
  93. int v = mp[u][i];
  94. if(g[v] || fa == v)continue;
  95. tmp = min(tmp, findg(v,u,sz));
  96. mx = max(mx, dp[v]);
  97. }
  98. mx = max(mx, sz - dp[u]);
  99. return min(tmp, pii(mx, u));
  100. }
  101.  
  102. void route(int u, int fa, vector<int>& ve, int sta){
  103. sta = ((<<a[u]) | sta);
  104. ve.pb(sta);
  105. for(int i=; i<mp[u].size(); i++){
  106. int v = mp[u][i];
  107. if(v == fa || g[v])continue;
  108. route(v, u, ve, sta);
  109. }
  110. }
  111.  
  112. ll cal(vector<int> &ve){
  113. // memset(cnt, 0, sizeof(cnt));
  114. for(int i=; i<; i++) cnt[i] = ;
  115.  
  116. for(int i=; i<ve.size(); i++){
  117. cnt[ve[i]] ++;
  118. }
  119.  
  120. /*
  121. Hash[it]-=1;
  122. ans+=Hash[(1<<m)-1];
  123. for(int j=it;j;j=(j-1)&it){
  124. ans+=Hash[((1<<m)-1)^j];
  125. }
  126. Hash[it]+=1;
  127. */
  128.  
  129. ll res = ;
  130. for(int i=; i<ve.size(); i++){
  131. int x = ve[i];
  132. cnt[ve[i]]--;
  133. res += 1ll*cnt[(<<k)-];
  134. for(int s = x; s; s = (s - ) & x){
  135. res += 1ll*cnt[((<<k)-) ^ s];
  136. }
  137. cnt[ve[i]]++;
  138. }
  139. return res;
  140. }
  141. void divide(int u){
  142. dfs(u,-);
  143. int rt = findg(u, -, dp[u]).se;
  144. g[rt] = ;
  145.  
  146. for(int i=; i<mp[rt].size(); i++){
  147. int v = mp[rt][i];
  148. if(g[v])continue;
  149. divide(v);
  150. }
  151.  
  152. vector<int>all;
  153. all.pb((<<a[rt]));
  154. for(int i=; i<mp[rt].size(); i++){
  155. vector<int>ve;
  156. int v = mp[rt][i];
  157. if(g[v])continue;
  158. route(v, -, ve, (<<a[rt]));
  159. ans -= 1ll*cal(ve);
  160. all.insert(all.end(),ve.begin(),ve.end());
  161. }
  162. ans += 1ll*cal(all);
  163. g[rt] = ;
  164. }
  165. int main(){
  166.  
  167. while(~scanf("%d%d", &n, &k)){
  168. for(int i=; i<=n; i++) scanf("%d", &a[i]), a[i]--;
  169. for(int i=; i<=n; i++) mp[i].clear();
  170. for(int i=; i< n; i++) {
  171. int u,v; scanf("%d%d", &u, &v);
  172. mp[u].pb(v); mp[v].pb(u);
  173. }
  174. if(k == ) {
  175. ans = 1ll*n*n;
  176. printf("%lld\n", ans);
  177. continue;
  178. }
  179. // memset(g,0,sizeof(g));
  180.  
  181. ans = ;
  182. divide();
  183. printf("%lld\n", ans);
  184. }
  185. return ;
  186. }

HDU-5977

HDU-5977 - Garden of Eden 点分治的更多相关文章

  1. HDU 5977 Garden of Eden(点分治求点对路径颜色数为K)

    Problem Description When God made the first man, he put him on a beautiful garden, the Garden of Ede ...

  2. HDU 5977 Garden of Eden (树分治+状态压缩)

    题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点? 析:对于路径,就是两类,第一种情况,就是跨过根结点,第二种是不跨过根结点,分别讨论就好 ...

  3. hdu 5977 Garden of Eden(点分治+状压)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5977 题解:这题一看就知道是状压dp然后看了一下很像是点分治(有点明显)然后就是简单的点分治+状压dp ...

  4. HDU 5977 Garden of Eden

    题解: 路径统计比较容易想到点分治和dp dp的话是f[i][j]表示以i为根,取了i,颜色数状态为j的方案数 但是转移这里如果暴力转移就是$(2^k)^2$了 于是用FWT优化集合或 另外http: ...

  5. HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)

    CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...

  6. HDU - 5977 Garden of Eden (树形dp+容斥)

    题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...

  7. hdu-5977 Garden of Eden(树分治)

    题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  8. HDU5977 Garden of Eden(树的点分治)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5977 Description When God made the first man, he ...

  9. Garden of Eden

    Garden of Eden Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

随机推荐

  1. JS面向对象编程(一):封装

    js是一门基于面向对象编程的语言.      如果我们要把(属性)和(方法)封装成一个对象,甚至要从原型对象生成一个实例,我们应该怎么做呢?  一.生成对象的原始模式            假定把猫看 ...

  2. CentOS 配置阿里云 NTP 服务

    NTP 是网络时间协议(Network Time Protocol),NTP 服务能保证服务器的本地时间与标准时间同步. ▶ 配置时区信息 1.删除系统里的当地时间链接 sudo rm /etc/lo ...

  3. 02 | 健康之路 kubernetes(k8s) 实践之路 : 生产可用环境及验证

    上一篇< 01 | 健康之路 kubernetes(k8s) 实践之路 : 开篇及概况 >我们介绍了我们的大体情况,也算迈出了第一步.今天我们主要介绍下我们生产可用的集群架设方案.涉及了整 ...

  4. 【MySQL】日常小技巧汇总,更新中……

    创建表时修改自增主键,添加 AUTO_INCREMENT=<Number> ,例如: CREATE TABLE `table_name` ( `id` int(11) unsigned N ...

  5. 【Android】Mac Android adb 配置

    打开终端,输入下面命令: touch .bash_profile open -e .bash_profile 即新建 “.bash_profile” 文件,并会弹出 “.bash_profile” 文 ...

  6. python redis连接 有序集合去重

    # -*- coding: utf-8 -*- import redisfrom constant import redis_ip, redis_db, redis_pw, logger, redis ...

  7. IO流与NIO流

    JAVA IO流最详解   (转自CSDN) IO流上:概述.字符流.缓冲区(java基础)   一.IO流概述 概述: IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间的数 ...

  8. S2:ArrayList

    1.ArrayList   ArrayList非常类似于数组,也有人称它为数组列表,ArrayList可以动态维护. 因为数组的长度是固定的,而SArrayList的容量可以根据需要自动扩充. Arr ...

  9. spring学习笔记之---bean管理的注解方式

    bean管理的注解方式 (一)使用注解定义bean (1)常用注解 (2)实例 1.在pom.xml中进行配置 <dependencies> <dependency> < ...

  10. tomcat和weblogic发布时,jar包内资源文件的读取路径问题

    问题场景: 本地使用的是tomcat作为发布容器,应用启动后一切正常: 发布测试环境服务器使用weblogic作为发布容器,发布后File类读取文件无法找到文件(路径错误). 问题原因: tomcat ...