题目大意 【gdoi2018 day2】第二题 滑稽子图(subgraph)
  • 给你一颗树\(T\),以及一个常数\(K\),对于\(T\)的点集\(V\)的子集\(S\).

  • 定义\(f(S)\)为点集\(S\)的导出子图的边数(一条原树中的边只有两个端点都出现在\(S\)中,才会出现在导出子图中)

数据范围

解题方案
\(Part_1\) 5%
  • 随便做
\(Part_2\) 30%
  • 考虑一下DP.

  • 设\(f[i][j][0/1]\)表示第\(i\)个点,导出子图边数为\(j\),第\(i\)个点是否选.

  • 转移讨论一下即可,这里需要注意一下转移时用顺推还是逆推.

  • 一般来说,对于背包类型的,我们顺推可以使每一个转移都是有效的.

  • 枚举之前子树大小和,以及当前子树大小,乘积的和是\(O(n^2)\)级别的.

  • 证明:

    • 两个点会产生贡献,当且仅当它们的\(LCA\)为当前的根时,每两个点的\(LCA\)唯一,故只有\(O(n^2)\)个点会产生贡献.
\(Part_3\) 100% DP
  • 依然是DP,但我们要利用好\(k\le 10\)这个特性.

  • 我们来观察一下顺推时的转移,其实可以表示为:

    • 令当前计算的是\(y\)对于父亲\(x\)的贡献,表达如下:

    \[f[x][i + j] = \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} f[x][i] * f[y][j] * (i + j) ^ k
    \]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

$$f[x][i + j] = \sum_{i = 0}^{size_x - 1}\sum_{j = 0}^{size_y - 1} f[x][i]f[y][j] * \sum_{t = 0}kitj^{k-t}\binom{k}{t}$$

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

$$f[x][i + j] = \sum_{i = 0}^{size_x - 1}\sum_{j = 0}^{size_y - 1} \sum_{t = 0}^k\binom{k}{t}f[x][i]
f[y][j] it*j{k-t}$$

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

$$f[x][i + j] = \sum_{i = 0}^{size_x - 1}\sum_{j = 0}^{size_y - 1} \sum_{t = 0}k\binom{k}{t}(f[x][i]*it) (f[y][j]
j^{k-t})$$

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

$$f[x][i + j] = \sum_{t = 0}^k\binom{k}{t}\sum_{i = 0}^{size_x - 1}\sum_{j = 0}^{size_y - 1} (f[x][i]i^t) (f[y][j]j^{k-t})$$

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

$$f[x][i + j] = \sum_{t = 0}^k\binom{k}{t}\sum_{i = 0}^{size_x - 1} (f[x][i]i^t)\sum_{j = 0}^{size_y - 1} (f[y][j]j^{k-t})$$

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

$$令g[x][t]表示\sum_{i = 0}{size_x-1}f[x][i]*it,则上式转化为$$

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

$$f[x][i + j] = \sum_{t = 0}^k\binom{k}{t}g[x][t]*g[y][k-t]$$

  • 我们发现实质上\(f\)的转移只与\(g\)有关,所以我们直接枚举指数\(k\)大小,\(O(k)\)转移即可.

  • 上述讨论的是当\(x,y\)两点不都选的时候,如果都选,转移应当如下:

\[f[x][i + j + 1] = \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} f[x][i] * f[y][j] * (i + j + 1) ^ k
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} f[x][i] * f[y][j] * (i + j + 1) ^ k
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} f[x][i] * f[y][j] * \sum_{t = 0}^k(i+j)^t*1^{k-t}*\binom{k}{t}
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1}\sum_{t = 0}^k f[x][i] * f[y][j] * (i+j)^t*\binom{k}{t}
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{t = 0}^k \binom{k}{t} \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} f[x][i] * f[y][j] * (i+j)^t
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{t = 0}^k \binom{k}{t} \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} f[x][i] * f[y][j] * \sum_{p = 0}^ti^p*j^{t-p}*\binom{t}{p}
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{t = 0}^k \binom{k}{t} \sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} \sum_{p = 0}^t \binom{t}{p}f[x][i] * f[y][j] * i^p*j^{t-p}
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{t = 0}^k \binom{k}{t} \sum_{p = 0}^t \binom{t}{p}\sum_{i = 0}^{size_x - 1}\sum_{j=0}^{size_y-1} f[x][i] * f[y][j] * i^p*j^{t-p}
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{t = 0}^k \binom{k}{t} \sum_{p = 0}^t \binom{t}{p}\sum_{i = 0}^{size_x - 1} (f[x][i] * i^p) \sum_{j=0}^{size_y-1} (f[y][j] *j^{t-p})
\]

\(\qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \Downarrow\)

\[f[x][i + j + 1] = \sum_{t = 0}^k \binom{k}{t} \sum_{p = 0}^t \binom{t}{p}g[x][p]*g[y][t-p]
\]

  • 可以发现,最后的转移,依然是只与\(g\)有关.

  • 转移一个点是\(O(k^2)\)的,\(n\)个点,故时间复杂度为\(O(n * k^3/6)\),实际上可以优化到\(O(n*k^2)\)

  • 注意,我们如果有\(a_1<a_2<\cdots a_n 且 (1\le\ a_i \le m)\),时间复杂度是\(O(\frac{n^m}{n!})\)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype> #define ll long long
#define I register int
#define L register ll
#define F(i, a, b) for (L i = a; i <= b; i ++)
#define mec(a, b) memcpy(a, b, sizeof a)
#define mem(a, b) memset(a, b, sizeof a)
#define add(a, b) ((a) = (a + b) % mo)
#define N 100100
#define M 2 * N
#define Get getchar()
#define mo 998244353 using namespace std; ll n, m, K, u, v, ans, sum, h, x, k;
ll F[N][11][2], G[N][11][2], jc[N], ny[N], d[N], bz[N];
ll nex[M], tov[M], las[N], last[N], tot; void R(L &x) {
char c = Get; x = 0; L t = 1;
for (; !isdigit(c); c = Get) t = (c == '-' ? -1 : t);
for (; isdigit(c); x = (x << 3) + (x << 1) + c - '0', c = Get); x = x * t;
} void W(L x) {
if (x < 0) { putchar('-'); W(-x); return; }
if (x > 9) W(x / 10); putchar(x % 10 + '0');
} void ins(L x, L y) { tov[++ tot] = y, nex[tot] = las[x], las[x] = tot; } ll ksm(L x, L y) {
L ans = 1;
while (y) {
if (y & 1) ans = (ans * x) % mo;
x = (x * x) % mo, y >>= 1;
}
return ans;
} ll C(L x, L y) { return jc[x] * ny[y] % mo * ny[x - y] % mo; } void Dg_dp() {
bz[1] = 1, d[h = 1] = 1;
while (h) { x = d[h], k = las[x];
if (k) {
if (!bz[tov[k]]) bz[tov[k]] = 1, d[++ h] = tov[k];
las[x] = nex[k];
}
if (!k) {
G[x][0][0] = G[x][0][1] = 1;
for (L k = last[x], y, s; k; k = nex[k])
if ((y = tov[k]) && (!bz[y])) {
mem(F[x], 0);
F(j, 0, K)
F(k, 0, j) {
add(F[x][j][0], G[x][k][0] * (G[y][j - k][0] + G[y][j - k][1]) % mo * C(j, k));
add(F[x][j][1], G[x][k][1] * (G[y][j - k][0]) % mo * C(j, k)); s = 0;
F(p, 0, k) add(s, G[x][p][1] * G[y][k - p][1] % mo * C(k, p));
add(F[x][j][1], C(j, k) * s);
}
F(j, 0, K) G[x][j][0] = F[x][j][0], G[x][j][1] = F[x][j][1];
}
bz[d[h --]] = 0;
} }
} int main() {
freopen("subgraph.in", "r", stdin);
freopen("subgraph.out", "w", stdout); R(n), R(m), R(K), jc[0] = ny[0] = 1;
F(i, 1, m) R(u), R(v), ins(u, v), ins(v, u);
F(i, 1, K) jc[i] = (jc[i - 1] * i) % mo, ny[i] = ksm(jc[i], mo - 2);
if (K == 0) { printf("%d", ksm(2, n)); return 0;}
mec(last, las), Dg_dp(), W((G[1][K][0] + G[1][K][1]) % mo);
}

【gdoi2018 day2】第二题 滑稽子图(subgraph)(性质DP+多项式)的更多相关文章

  1. 【gdoi2018 day2】第二题 滑稽子图

    题意: 给出一棵树.设\(E\)表示边集,\(V\)表示点集,\(S\)为\(V\)的一个子集. \(f(S)=|(u,v)|(u,v)\in E \ \&\&\ u\in V\ \& ...

  2. SPOJ 1479 +SPOJ 666 无向树最小点覆盖 ,第二题要方案数,树形dp

    题意:求一颗无向树的最小点覆盖. 本来一看是最小点覆盖,直接一下敲了二分图求最小割,TLE. 树形DP,叫的这么玄乎,本来是线性DP是线上往前\后推,而树形DP就是在树上,由叶子结点状态向根状态推. ...

  3. test20181020 B君的第二题

    题意 分析 考场70分 一看就是裸的kmp,直接打上去. #include<cstdlib> #include<cstdio> #include<cmath> #i ...

  4. NOIP2011 day2 第一题 计算系数

    计算系数 NOIP2011 day2 第一题 描述 给定一个多项式(ax+by)^k,请求出多项式展开后x^n*y^m项的系数. 输入格式 共一行,包含5 个整数,分别为 a ,b ,k ,n ,m, ...

  5. 05:统计单词数【NOIP2011复赛普及组第二题】

    05:统计单词数 总时间限制:  1000ms 内存限制:  65536kB 描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次 ...

  6. 常见面试第二题之什么是Context

    今天的面试题,也就是我们常见面试题系列的第二题,我们来讲一讲android中的context.我相信大家android开发者一定对于这个context非常熟悉,肯定都有使用过,肯定没有没使用过的.但是 ...

  7. 《学习OpenCV》练习题第五章第二题abc

    代码: #include <stdio.h> #include <opencv/highgui.h> #include <opencv/cv.h> #include ...

  8. 《学习OpenCV》练习题第四章第二题

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  9. CSDN挑战编程——《金色十月线上编程比赛第二题:解密》

    金色十月线上编程比赛第二题:解密 题目详情: 小强是一名学生, 同一时候他也是一个黑客. 考试结束后不久.他吃惊的发现自己的高等数学科目竟然挂了,于是他果断入侵了学校教务部站点. 在入侵的过程中.他发 ...

随机推荐

  1. 测者的测试技术手册:自动化单元工具EvoSuie的代码覆盖报告

    EvoSuite是由Sheffield等大学联合开发的一种开源工具,用于自动生成测试用例集,生成的测试用例均符合Junit的标准,可直接在Junit中运行.得到了Google和Yourkit的支持. ...

  2. PJSUA2开发文档--第十章 媒体质量(MEDIA QUALITY)

    10 媒体质量(Media Quality) 10.1 音频质量 如果遇到音频质量问题,可尝试以下步骤: 遵循指南:使用pjsystest测试声音设备. 识别声音问题并使用以下步骤进行故障排除:检查声 ...

  3. MySQL索引设计需要考虑哪些因素?

    索引小知识 篇幅有限,索引的基本知识我们就不赘述了,在此,我们尝试说明其中的一个小点-----B+树与B树的区别到底是什么. InnoDB是使用B+树来实现其索引功能的.在B+树中,内节点(非叶子节点 ...

  4. Linux中DHCP服务器的简单配置

    我安装了两台linux系统,一个作为服务器,一个客户端 两个都有3个网卡, 后两个网卡聚合为zhi一个网卡:Linux 网卡聚合 两台电脑都一样. 那么如何为这个聚合网卡进行DHCP的分配呢? 1.由 ...

  5. ORACLE如何检查找出损坏索引(Corrupt Indexes)

      在Oracle数据库中如何找出损坏索引呢? 下面我们人为构造一个案例,将索引块损坏.如下案例所示: SQL> create tablespace test_data   2  datafil ...

  6. SQLServer之通过视图修改数据

    通过视图增删改数据注意事项 需要对目标表的 UPDATE.INSERT 或 DELETE 权限(取决于执行的操作). 如果视图引用多个基表,则不能删除行. 如果视图引用多个基表,只能更新属于单个基表的 ...

  7. zabbix监控Oracle

    可监控项 使用zabbix监控oracle数据库需要借助第三方的插件,目前使用较多的是orabbix.目前维护到了1.2.3版本.关于oracle自带的监控项目有以下几个: DB Version (i ...

  8. SQLServer之FOREIGN KEY约束

    FOREIGN KEY约束添加规则 1.外键约束并不仅仅可以与另一表的主键约束相链接,它还可以定义为引用另一个表中 UNIQUE 约束的列. 2.如果在 FOREIGN KEY 约束的列中输入非 NU ...

  9. Java学习笔记记录(二)

    1.复合语句 if条件语句 使用场景:boolean类型判断.一个范围的判断.几个常量值的判断 有左大括号就没有分号,有分号就没有左大括号. 如下: public class demo1 { stat ...

  10. eclipse 中 git 解决冲突(重点)

    Eclipse 中 GIT 提交代码时的冲突困扰了我很久,说实在的,真的感觉 GIT 太特么难用了,尤其是提交代码时(或许还没习惯吧).特此,写一篇博文记录一下自己使用 GIT 决解冲突的问题,希望能 ...