【bzoj3162】独钓寒江雪
*题目描述:
*题解:
树哈希+组合数学。对于树的形态相同的子树就一起考虑。
*代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif
#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
R char ch; R int cnt = 0; R bool minus = 0;
while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ? minus = 1 : cnt = ch - '0';
while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus ? -cnt : cnt;
}
#define maxn 500010
#define maxm 1000010
struct Edge
{
int to;
Edge *next, *rev;
}*last[maxn], e[maxm], *ecnt = e;
inline void link(R int a, R int b)
{
*++ecnt = (Edge) {b, last[a], ecnt + 1}; last[a] = ecnt;
*++ecnt = (Edge) {a, last[b], ecnt - 1}; last[b] = ecnt;
}
int rt[2], rtcnt, size[maxn], n, root;
void dfs(R int x, R int fa)
{
size[x] = 1;
R int maxx = 0;
for (R Edge *iter = last[x]; iter; iter = iter -> next)
{
R int pre = iter -> to;
if (pre != fa)
{
dfs(pre, x);
size[x] += size[pre];
cmax(maxx, size[pre]);
}
}
cmax(maxx, n - size[x]);
if (maxx <= n >> 1) rt[rtcnt++] = x;
}
int p[maxn], inp[maxn];
const int mod = 1e9 + 7;
inline int qpow(R int x, R int power)
{
R int base = x, ans = 1;
for ( ; power; power >>= 1, base = 1ll * base * base % mod)
if (power & 1) ans = 1ll * ans * base % mod;
return ans;
}
inline void prepare()
{
R int _ = maxn - 1, tmp = 1;
for (R int i = 2; i <= _; ++i)
tmp = 1ll * tmp * i % mod;
inp[_] = qpow(tmp, mod - 2);
for (R int i = _ - 1; ~i; --i)
inp[i] = 1ll * inp[i + 1] * (i + 1) % mod;
}
inline int C(R long long n, R int m)
{
n %= mod; R long long tmp = 1;
for (R int i = 1; i <= m; ++i) tmp = tmp * (n - i + 1) % mod;
return tmp * inp[m] % mod;
}
inline int cl(R long long n, R int k)
{
return C(n + k - 1, k);
}
//cl表示在n种无限多的物品内取k个的方案数
unsigned long long hash[maxn], hash2[maxn];
int st[maxn], top;
long long f[maxn][2]; //f[x][0..1]表示x节点取或者不取的方案数
inline bool cmp(R int x, R int y)
{
return hash[x] > hash[y];
}
void dp(R int x, R int fa)
{
f[x][0] = f[x][1] = 1ll;
for (R Edge *iter = last[x]; iter; iter = iter -> next)
if (iter -> to != fa)
dp(iter -> to, x);
top = 0;
for (R Edge *iter = last[x]; iter; iter = iter -> next)
if (iter -> to != fa)
st[++top] = iter -> to;
std::sort(st + 1, st + top + 1, cmp);
for (R int i = 1, j; i <= top; i = j)
{
for (j = i + 1; j <= top && hash[st[i]] == hash[st[j]] && hash2[st[i]] == hash2[st[j]]; ++j);
f[x][0] = f[x][0] * cl(f[st[i]][0] + f[st[i]][1], j - i) % mod;
f[x][1] = f[x][1] * cl(f[st[i]][0], j - i) % mod;
}
hash[x] = 123;
for (R int i = 1; i <= top; ++i)
hash[x] = (hash[x] * 1999 + 233 * hash[st[i]]) % 998244353;
hash2[x] = 123;
for (R int i = 1; i <= top; ++i)
hash2[x] = (hash2[x] * 12579 + (hash2[st[i]] * 233)) % mod;
}
int main()
{
// setfile();
n = FastIn(); prepare();
for (R int i = 1; i < n; ++i)
{
R int a = FastIn(), b = FastIn();
link(a, b);
}
dfs(1, 0);
if (rtcnt == 2)
{
R Edge *iter;
for (iter = last[rt[0]]; iter; iter = iter -> next)
if (iter -> to == rt[1])
{
iter -> to = iter -> rev -> to = ++n;
break;
}
*++ecnt = (Edge) {rt[0], last[n], ecnt}; last[n] = ecnt;
*++ecnt = (Edge) {rt[1], last[n], ecnt}; last[n] = ecnt;
root = n;
}
else root = rt[0];
dp(root, 0);
R long long ans;
if (rtcnt == 1)
ans = (f[root][0] + f[root][1]) % mod;
else
{
R int x = rt[0], y = rt[1];
if (hash[x] == hash[y])
ans = f[x][0] * f[y][1] % mod + cl(f[x][0], 2) % mod;
else
ans = (f[x][0] * f[y][0] % mod + f[x][0] * f[y][1] % mod + f[x][1] * f[y][0] % mod) % mod;
}
printf("%lld\n", ans % mod );
return 0;
}
/*
input:
6
1 2
1 3
1 4
4 5
4 6
output:
9
*/
【bzoj3162】独钓寒江雪的更多相关文章
- BZOJ3162 独钓寒江雪(哈希+树形dp)
数独立集显然是可以树形dp的,问题在于本质不同. 假设已经给树确立了一个根并且找到了所有等效(注意是等效而不是同构)子树,那么对转移稍加修改使用隔板法就行了. 关键在于找等效子树.首先将树的重心(若有 ...
- [bzoj3162]独钓寒江雪_树hash_树形dp
独钓寒江雪 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3162 题解: 首先,如果没有那个本质相同的限制这就是个傻逼题. 直接树形dp ...
- [BZOJ3162]独钓寒江雪
bzoj description 你要给一个树上的每个点黑白染色,要求白点不相邻.求本质不同的染色方案数. 两种染色方案本质相同当且仅当对树重新标号后对应节点的颜色相同. \(n\le 5\times ...
- bzoj3162独钓寒江雪
题意 \(n\)阶树,求本质不同的独立集个数 做法 重新编号后重心是不变的,如果有两个重心,可以加个虚点 用树哈希判子树有多少个相同的子树,设某种有\(k\)个,如果原本方案数为\(x\)个 则方案数 ...
- liaoliao的四连做第二弹
liaoliao四连做第一弹 1.bzoj3211: 花神游历各国 由于$10^9$以内的数最多只会被开方$10$次,所以我们可以用线段树维护然后剪枝.. #include <cstdio> ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
- 【BZOJ3162】独钓寒江雪(树哈希,动态规划)
[BZOJ3162]独钓寒江雪(树哈希,动态规划) 题面 BZOJ 题解 忽然翻到这道题目,突然发现就是前几天一道考试题目... 题解: 树哈希,既然只考虑这一棵树,那么,如果两个点为根是同构的, 他 ...
- 【BZOJ3162】独钓寒江雪 树同构+DP
[BZOJ3162]独钓寒江雪 题解:先进行树hash,方法是找重心,如果重心有两个,则新建一个虚点将两个重心连起来,新点即为新树的重心.将重心当做根进行hash,hash函数不能太简单,我的方法是: ...
- [BZOJ:3162]:独钓寒江雪
题解: 求本质不同的独立集的个数 首先独立集的个数是很好做的 \(f[u][0/1]\)表示节点\(u\)不选/选的方案数 然后dp就是 \(f[u][0] = f[u][0] * (f[v][0] ...
随机推荐
- Scratch少儿编程系列:(七)太阳系八大行星的运转
一.程序说明 本程序用来模拟太阳系八大行星的运转过程. 二.程序流程图 为了更直观的描述上述过程,采用流程图的方式将猜数字的过程进行描述. 还在制作中... 三.制作过程 1. 场景和角色的选择 场景 ...
- PIL实现图片框架以及生成图片验证码
1. PIL的基本概念 PIL:即Python Imaging Library,是Python平台事实上的图像处理标准库. PIL中涉及通道(bands)和模式(mode)这两个重要概念. (1)通道 ...
- 面试题:线程A打印1-10数字,打印到第5个数字时,通知线程B
此题考查的是线程间的通信方式. 可以利用park/unpark实现 可以利用volatile关键字实现 可以利用synchronized结合wait notify实现 可以利用JUC中的CountDo ...
- [19/09/19-星期四] Python中的字典和集合
一.字典 # 字典 # 使用 {} 来创建字典 d = {} # 创建了一个空字典 # 创建一个保护有数据的字典 # 语法: # {key:value,key:value,key:value} # 字 ...
- layui动态渲染select等组件并初始化赋值失败
描诉:有一个用户信息form表单,其中有部门单选框,数据库中有一张dept(部门)表,要动态渲染出所有部门,并默认选中用户所在部门 关键代码: html页面 <div class="l ...
- Java语言的发展历程
前言 自1946年2月14日世界上首款计算机ENAC问世,第一代计算机语言“机器语言”便诞生了,它使用的是最原始的穿孔卡片,这种卡片上使用的语言只有专家才能理解,与人类语言差别极大.这种语言本质上是计 ...
- [Codeforces 1239D]Catowise City(2-SAT)
[Codeforces 1239D]Catowise City(2-SAT) 题面 有n个主人,每个主人都有一只猫.每个主人认识一些猫(包括自己的猫).现在要选出一些人和一些猫,个数均大于0且总共为n ...
- php strpos() 函数介绍与使用方法详解
本文主要和大家介绍PHP中mb_strpos的使用技巧,通过使用语法以及实例给大家详细分析了用法,需要的朋友参考学习下.希望能帮助到大家.mb_strpos(PHP 4 >= 4.0.6, PH ...
- Api接口管理工具推荐
在App开发过程中少不了跟服务端打交道,各种HTTP接口调试.返回数据处理占据了不少开发时间,一款好的接口管理工具就非常有必要了.接口管理工具一方面起到链接后台开发人员和App开发人员的作用,另一方面 ...
- 46. Permutations (JAVA)
Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] O ...