HDU-5977 - Garden of Eden 点分治
题意:
给定一颗树,问树上有多少节点对,节点对间包括了所有K种苹果。
思路:
点分治,对于每个节点记录从根节点到这个节点包含的所有情况,类似状压,因为K《=10。然后处理每个重根连着的点的值:直接枚举每个点,然后找出这个点对应的每个子集,累计和子集互补的个数。
枚举一个数的子集,例如1010,它的子集包括1010,1000,0010,0000.这里有个技巧:
for(int s = x; s; s = (s - ) & x){
res += 1ll*cnt[((<<k)-) ^ s];
}
//#pragma GCC optimize(3)
//#pragma comment(linker, "/STACK:102400000,102400000") //c++
// #pragma GCC diagnostic error "-std=c++11"
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") #include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define OKC ios::sync_with_stdio(false);cin.tie(0)
#define FT(A,B,C) for(int A=B;A <= C;++A) //用来压行
#define REP(i , j , k) for(int i = j ; i < k ; ++i)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c);
//priority_queue<int ,vector<int>, greater<int> >que; const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e9+;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /*-----------------------showtime----------------------*/ const int maxn = ;
int a[maxn],g[maxn],dp[maxn],cnt[maxn];
vector<int>mp[maxn];
int n,k;
ll ans = ; void dfs(int u,int fa){
dp[u] = ;
for(int i=; i<mp[u].size(); i++){
int v = mp[u][i];
if(g[v] || fa == v)continue;
dfs(v, u);
dp[u] += dp[v];
}
}
pii findg(int u,int fa, int sz){
int mx = ;
pii tmp = pii(inf, u); for(int i=; i<mp[u].size(); i++){
int v = mp[u][i];
if(g[v] || fa == v)continue;
tmp = min(tmp, findg(v,u,sz));
mx = max(mx, dp[v]);
}
mx = max(mx, sz - dp[u]);
return min(tmp, pii(mx, u));
} void route(int u, int fa, vector<int>& ve, int sta){
sta = ((<<a[u]) | sta);
ve.pb(sta);
for(int i=; i<mp[u].size(); i++){
int v = mp[u][i];
if(v == fa || g[v])continue;
route(v, u, ve, sta);
}
} ll cal(vector<int> &ve){
// memset(cnt, 0, sizeof(cnt));
for(int i=; i<; i++) cnt[i] = ; for(int i=; i<ve.size(); i++){
cnt[ve[i]] ++;
} /*
Hash[it]-=1;
ans+=Hash[(1<<m)-1];
for(int j=it;j;j=(j-1)&it){
ans+=Hash[((1<<m)-1)^j];
}
Hash[it]+=1;
*/ ll res = ;
for(int i=; i<ve.size(); i++){
int x = ve[i];
cnt[ve[i]]--;
res += 1ll*cnt[(<<k)-];
for(int s = x; s; s = (s - ) & x){
res += 1ll*cnt[((<<k)-) ^ s];
}
cnt[ve[i]]++;
}
return res;
}
void divide(int u){
dfs(u,-);
int rt = findg(u, -, dp[u]).se;
g[rt] = ; for(int i=; i<mp[rt].size(); i++){
int v = mp[rt][i];
if(g[v])continue;
divide(v);
} vector<int>all;
all.pb((<<a[rt]));
for(int i=; i<mp[rt].size(); i++){
vector<int>ve;
int v = mp[rt][i];
if(g[v])continue;
route(v, -, ve, (<<a[rt]));
ans -= 1ll*cal(ve);
all.insert(all.end(),ve.begin(),ve.end());
}
ans += 1ll*cal(all);
g[rt] = ;
}
int main(){ while(~scanf("%d%d", &n, &k)){
for(int i=; i<=n; i++) scanf("%d", &a[i]), a[i]--;
for(int i=; i<=n; i++) mp[i].clear();
for(int i=; i< n; i++) {
int u,v; scanf("%d%d", &u, &v);
mp[u].pb(v); mp[v].pb(u);
}
if(k == ) {
ans = 1ll*n*n;
printf("%lld\n", ans);
continue;
}
// memset(g,0,sizeof(g)); ans = ;
divide();
printf("%lld\n", ans);
}
return ;
}
HDU-5977
HDU-5977 - Garden of Eden 点分治的更多相关文章
- 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 ...
- HDU 5977 Garden of Eden (树分治+状态压缩)
题意:给一棵节点数为n,节点种类为k的无根树,问其中有多少种不同的简单路径,可以满足路径上经过所有k种类型的点? 析:对于路径,就是两类,第一种情况,就是跨过根结点,第二种是不跨过根结点,分别讨论就好 ...
- hdu 5977 Garden of Eden(点分治+状压)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5977 题解:这题一看就知道是状压dp然后看了一下很像是点分治(有点明显)然后就是简单的点分治+状压dp ...
- HDU 5977 Garden of Eden
题解: 路径统计比较容易想到点分治和dp dp的话是f[i][j]表示以i为根,取了i,颜色数状态为j的方案数 但是转移这里如果暴力转移就是$(2^k)^2$了 于是用FWT优化集合或 另外http: ...
- HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)
CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...
- HDU - 5977 Garden of Eden (树形dp+容斥)
题意:一棵树上有n(n<=50000)个结点,结点有k(k<=10)种颜色,问树上总共有多少条包含所有颜色的路径. 我最初的想法是树形状压dp,设dp[u][S]为以结点u为根的包含颜色集 ...
- hdu-5977 Garden of Eden(树分治)
题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- HDU5977 Garden of Eden(树的点分治)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5977 Description When God made the first man, he ...
- Garden of Eden
Garden of Eden Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
随机推荐
- 网站性能优化的方法--Yahoo
如何能让用户更快的打开我们的网页? 1.尽可能减少HTTP请求数 2.使用CDN(内容分发网络) 3.添加Expire/Cache-Control头 4.启用Gzip压缩 5.将CSS放在页面最上面 ...
- 【iOS】UIAlertView 点击跳转事件
iOS 开发中,UIAlertView 经常用到.这里记录下曾用到的点击跳转事件. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@& ...
- 彻底理解kubernetes CNI
kubernetes各版本离线安装包 CNI接口很简单,特别一些新手一定要克服恐惧心里,和我一探究竟,本文结合原理与实践,认真读下来一定会对原理理解非常透彻. 环境介绍 我们安装kubernetes时 ...
- HC-08 BLE资料
1.1 特点简介 HC-08蓝牙串口通信模块是新一代的基于Bluetooth Specification V4.0 BLE蓝牙协议的数传模块.无线工作频段为 2.4GHz ISM,调制方式是 GFSK ...
- spring boot 学习笔记之前言----环境搭建(如何用Eclipse配置Maven和Spring Boot)
本篇文档来源:https://blog.csdn.net/a565649077/article/details/81042742 1.1 Eclipse准备 (1) 服务器上安装JDK和Mav ...
- JavaSE(一)Java程序的三个基本规则-组织形式,编译运行,命名规则
一.Java程序的组织形式 Java程序是一种纯粹的面向对象的程序设计语言,因此Java程序必须以类(class)的形式存在,类(class)是Java程序的最小程序单位. J ...
- 9-2、大型项目的接口自动化实践记录----递归判断两个json串是否相等
1.已知json串构成的情况下判断 先构造一下场景,假设已经把各个数据都移除掉不对比的字段 图1 预期.实际结果,复杂接口返回多层嵌套json时,同下 图2 预期.实际结果值为:{child_json ...
- zookeeper基本知识入门(一)
之前我们在搭建hadoop分布式环境的时候用到过Zookeeper注册hadoop服务.那么到底Zookeeper在分布式环境中发挥了什么作用呢,这次我们就来讨论这个问题. 在分布式系统中通常都会有多 ...
- Netty学习(六)-LengthFieldBasedFrameDecoder解码器
在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...
- PowerShell安装IIS
Windows作web开发的同学,应该都会用到IIS服务器.比如在阿里云或是Azure上购买一台新的服务器,默认是没有安装IIS的(安装的镜像就带有IIS或是MySql的除外).届时需要安装IIS,安 ...