题目简述:给定$n \leq 10^5$个节点的无根树,以及$q \leq 10^5$个询问。每个询问给定$k \leq 10^5$个不同的节点$a_1, a_2, \dots, a_k$,以及参数$1 \leq r \leq n, 1 \leq m \leq \min\{k, 300\}$,求将这$k$个节点分成不超过$m$组(本质不同)的方案数,使得

  ·每组节点至少有一个;

  ·以$r$为根时,任意节点的祖先不与该节点同组。

解:code

对每组询问,令$h[a_i]$表示$a_1, a_2, \dots, a_k$中$a_i$的祖先(不含自身)的个数。按$h[a_i]$从小到大排序$a_i$后,令$F[i][j]$表示前$i$个节点分成$j$组(本质不同)的合法方案数,则

$$ F[i][j] = (j-h[a_i])F[i-1][j]+F[i-1][j-1], $$

特别地,$F[0][j] = [j = 0]$。动态规划的复杂度为$O(mk)$。

现在的问题是,如何求得$h[a_i]$。若令$h_1[a_i]$表示以节点$1$为根时,$a_1, a_2, \dots, a_k$中$a_i$的祖先(含自身)的个数,则

$$ h[a_i] = h_1[a_i]+h_1[r]-2h_1[\text{LCA}(a_i, r)]+[\text{LCA}(a_i, r) \in \{a_1, a_2, \dots, a_k\}]-1, $$

其中$\text{LCA}(u, v)$表示$u$和$v$的最近公共祖先。

而$h_1[]$易于计算的,我们可以求树以节点$1$为根的DFS序,则$h_1[]$的维护可化为“区间修改”和“单点询问”的线段树问题。

求LCA的时间复杂度为$O(n\log n)$预处理以及$O(\log n)$单次询问。(其实可以将LCA转化为$\pm 1$RMQ问题,做到$O(n)$预处理以及$O(1)$单次询问。但这并不是重点。)

从而总的时间复杂度为$O(n\log n + K (m+\log n))$,其中$K$为所有询问的$k$之和。

解2:

计算$h[a_i]$可以看做是$a_i$至$r$的树链上的求和,可以用树链剖分在$O(k \log^2 n)$的时间复杂度内直接求得,而不需要经过任何问题的转化。

CodeForces 1111E. Tree的更多相关文章

  1. Tree CodeForces - 1111E (树,计数,换根)

    大意: 给定树, 多组询问, 每个询问给出一个点集$S$, 给定$m, r$, 求根为$r$时, $S$的划分数, 满足 每个划分大小不超过$m$ 每个划分内不存在一个点是另一个点的祖先 设点$x$的 ...

  2. Codeforces 675D Tree Construction Splay伸展树

    链接:https://codeforces.com/problemset/problem/675/D 题意: 给一个二叉搜索树,一开始为空,不断插入数字,每次插入之后,询问他的父亲节点的权值 题解: ...

  3. Codeforces 570D TREE REQUESTS dfs序+树状数组 异或

    http://codeforces.com/problemset/problem/570/D Tree Requests time limit per test 2 seconds memory li ...

  4. Codeforces 570D - Tree Requests【树形转线性,前缀和】

    http://codeforces.com/contest/570/problem/D 给一棵有根树(50w个点)(指定根是1号节点),每个点上有一个小写字母,然后有最多50w个询问,每个询问给出x和 ...

  5. Codeforces 23E Tree

    http://codeforces.com/problemset/problem/23/E 题意:给一个树,求砍断某些边,使得所有联通块大小的乘积最大.思路:f[i][j]代表当前把j个贡献给i的父亲 ...

  6. Codeforces 1092F Tree with Maximum Cost(树形DP)

    题目链接:Tree with Maximum Cost 题意:给定一棵树,树上每个顶点都有属性值ai,树的边权为1,求$\sum\limits_{i = 1}^{n} dist(i, v) \cdot ...

  7. [Educational Round 17][Codeforces 762F. Tree nesting]

    题目连接:678F - Lena and Queries 题目大意:给出两个树\(S,T\),问\(S\)中有多少连通子图与\(T\)同构.\(|S|\leq 1000,|T|\leq 12\) 题解 ...

  8. Codeforces 911F Tree Destruction

    Tree Destruction 先把直径扣出来, 然后每个点都和直径的其中一端组合, 这样可以保证是最优的. #include<bits/stdc++.h> #define LL lon ...

  9. CodeForces 570D - Tree Requests - [DFS序+二分]

    题目链接:https://codeforces.com/problemset/problem/570/D 题解: 这种题,基本上容易想到DFS序. 然后,我们如果再把所有节点分层存下来,那么显然可以根 ...

随机推荐

  1. Android开发之实现锁屏功能

    锁屏须要引入设备超级管理员.在文档Android开发文档的Administration中有具体的说明. Android设备管理系统功能和控制訪问. 主要有一下几个步骤: 1  创建广播接收者,实现De ...

  2. DateTime操作,时间范围,加减

    DB里边存的是char类型数组的时间,例如20151111 12171220000,现在需要把这个时间加减5s,组成 一个时间范围 然后再写存储过程. 想到的办法就是把这个时间先转换成DateTime ...

  3. Mataplotlib绘图和可视化

    Mataplotlib是一个强大的python绘图和数据可视化工具包 安装方法:pip install matplotlib 引用方法:import matplotlib.pyplot as plt ...

  4. Linux多线程编程的条件变量

    在stackoverflow上看到一关于多线程条件变量的问题,题主问道:什么时候会用到条件变量,mutex还不够吗?有个叫slowjelj的人做了很好的回答,我再看这个哥们其他话题的一些回答,感觉水平 ...

  5. C++ 中的几种初始化

    前言 阅读C++教材时,想必你听过复制初始化,直接初始化,值初始化这三个概念吧.笔者本人常将其混淆,遂在此记录下它们的具体含义以便日后查阅. 复制初始化( copy-initialization ) ...

  6. 九度OJ 1126:打印极值点下标 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4613 解决:1646 题目描述: 在一个整数数组上,对于下标为i的整数,如果它大于所有它相邻的整数, 或者小于所有它相邻的整数,则称为该整 ...

  7. java CyclicBarrier和wait/notifyAll

    1 CyclicBarrier 多个进程做自己的事情,然后先做完的就等待在CyclicBarrier上,然后最后一个做完的线程到来时会冲破CyclicBarrier,然后执行CyclicBarrier ...

  8. windows server安装oracle

    倒腾windows server的时候一定要先整net framework然后再安装oracle不然连不上或者装一下client 也能连上但是为了不安装client一定要先装framework!

  9. windows server 2008 + IIS 7.5实现多用户FTP(多账号对应不同目录

    在windows server 2003 + IIS 6 的时候,就已经能实现多用户FTP的功能,不过设置有写繁琐,如果站点多的话,设置账号.权限这些东西都要搞很久.Windows server 20 ...

  10. HDU5877 Weak Pair dfs + 线段树/树状数组 + 离散化

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5877 题意: weak pair的要求: 1.u是v的祖先(注意不一定是父亲) 2.val[u]*va ...