\(\mathcal{Description}\)

  Link.

  给定一个含 \(n\) 个点 \(m\) 条边的 DAG,有两枚初始在 1 号点和 2 号点的棋子。两人博弈,轮流移动其中一枚棋子到邻接结点位置,无法移动者负。求 \(2^m\) 个边集中,加入图中能使先手必胜的方案数。答案对 \(10^9+7\) 取模。

  \(n\le15\)。

\(\mathcal{Solution}\)

  先从博弈角度思考:两枚棋子显然独立,那么先手必胜等价于 \(\operatorname{sg}(1)\not=\operatorname{sg}(2)\),其中,\(\operatorname{sg}\) 有

\[\operatorname{sg}(u)=\operatorname{mex}_{v\in\operatorname{adj}(u)}\operatorname{sg}(v)
\]

在不同边集的情况中,\(\operatorname{adj}(u)\) 有所改变,所以情况不同。

  接下来,方便起见,尝试计数 \(\operatorname{sg}(1)=\operatorname{sg}(2)\) 的情况。令 \(f(S)~(1,2\in S)\) 表示仅考虑点集 \(S\) 的导出子图时,\(\operatorname{sg}(1)=\operatorname{sg}(2)\) 的方案数。而 DP 中的“子问题”源于 \(\operatorname{sg}\) 函数中 \(\operatorname{mex}\) 的定义——如果我们挑除所有 \(\operatorname{sg}(u)=0\) 的 \(u\)(一定存在)及其邻接边,剩下的子图仍然是同类问题,只是所有 \(\operatorname{sg}\) 值减少 \(1\),不影响 DP 定义,这就是转移的雏形。具体地,枚举点集 \(T\subseteq S\),钦定其中所有点的 \(\operatorname{sg}\) 非 \(0\),考虑:

  • \(1,2\in T\),\(T\) 中每个点至少连向一个 \(S-T\) 中的点,其余边任意(注意 \(T\) 中的边是子问题,不考虑)。

  • \(1,2\not\in T\),已经满足条件,在上种情况的基础上加上 \(T\) 中边任选的方案,直接贡献。

  综上,复杂度 \(\mathcal O(3^nn)\)。

\(\mathcal{Code}\)

  1. /* Clearink */
  2. #include <cstdio>
  3. #define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
  4. #define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i )
  5. const int MAXN = 15, MAXM = MAXN * ( MAXN - 1 ) >> 1, MOD = 1e9 + 7;
  6. int n, m, pwr[MAXM + 5], conc[1 << MAXN][MAXN], f[1 << MAXN];
  7. bool adj[MAXN + 5][MAXN + 5];
  8. inline int mul( const long long a, const int b ) { return a * b % MOD; }
  9. inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
  10. inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
  11. inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
  12. inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
  13. int main() {
  14. scanf( "%d %d", &n, &m ), pwr[0] = 1;
  15. rep ( i, 1, m ) {
  16. pwr[i] = add( pwr[i - 1], pwr[i - 1] );
  17. int u, v; scanf( "%d %d", &u, &v );
  18. adj[u - 1][v - 1] = true;
  19. }
  20. rep ( S, 1, ( 1 << n ) - 1 ) {
  21. int v = 0; for ( ; !( S >> v & 1 ); ++v );
  22. rep ( u, 0, n - 1 ) conc[S][u] = conc[S ^ 1 << v][u] + adj[u][v];
  23. }
  24. rep ( S, 0, ( 1 << n ) - 1 ) if ( ( S & 3 ) == 3 ) {
  25. f[S] = 1;
  26. for ( int T = S & ( S - 1 ); T; T = ( T - 1 ) & S ) {
  27. if ( T & 1 && T & 2 ) {
  28. int coe = 1;
  29. rep ( u, 0, n - 1 ) if ( S >> u & 1 ) {
  30. if ( T >> u & 1 ) {
  31. coe = mul( coe, pwr[conc[S ^ T][u]] - 1 );
  32. } else {
  33. coe = mul( coe, pwr[conc[T][u]] );
  34. }
  35. }
  36. addeq( f[S], mul( coe, f[T] ) );
  37. } else if ( !( T & 1 || T & 2 ) ) {
  38. int coe = 1;
  39. rep ( u, 0, n - 1 ) if ( S >> u & 1 ) {
  40. if ( T >> u & 1 ) {
  41. coe = mul( coe,
  42. mul( pwr[conc[S ^ T][u]] - 1, pwr[conc[T][u]] ) );
  43. } else {
  44. coe = mul( coe, pwr[conc[T][u]] );
  45. }
  46. }
  47. addeq( f[S], coe );
  48. }
  49. }
  50. }
  51. printf( "%d\n", sub( pwr[m], f[( 1 << n ) - 1] ) );
  52. return 0;
  53. }

Solution -「AGC 016F」Games on DAG的更多相关文章

  1. Solution -「AGC 036D」「AT 5147」Negative Cycle

    \(\mathcal{Descriprtion}\)   Link.   在一个含 \(n\) 个结点的有向图中,存在边 \(\lang i,i+1,0\rang\),它们不能被删除:还有边 \(\l ...

  2. Solution -「AGC 026D」Histogram Coloring

    \(\mathcal{Description}\)   Link.   有 \(n\) 列下底对齐的方格纸排成一行,第 \(i\) 列有 \(h_i\) 个方格.将每个方格染成黑色或白色,求使得任意完 ...

  3. Solution -「AGC 004E」「AT 2045」Salvage Robots

    \(\mathcal{Description}\)   Link.   有一个 \(n\times m\) 的网格.每个格子要么是空的,要么有一个机器人,要么是一个出口(仅有一个).每次可以命令所有机 ...

  4. Solution -「AGC 012F」「AT 2366」Prefix Median

    \(\mathcal{Description}\)   Link.   给定序列 \(\{a_{2n-1}\}\),将 \(\{a_{2n-1}\}\) 按任意顺序排列后,令序列 \(b_i\) 为前 ...

  5. Solution -「AGC 010C」「AT 2304」Cleaning

    \(\mathcal{Description}\)   Link.   给定一棵 \(n\) 个点的无根树,点有点权,每次选择两个不同的叶子,使它们间的简单路径的所有点权 \(-1\),问能否将所有点 ...

  6. Solution -「AGC 019E」「AT 2704」Shuffle and Swap

    \(\mathcal{Description}\)   Link.   给定 \(01\) 序列 \(\{A_n\}\) 和 \(\{B_n\}\),其中 \(1\) 的个数均为 \(k\).记 \( ...

  7. Solution -「AGC 019F」「AT 2705」Yes or No

    \(\mathcal{Description}\)   Link.   有 \(n+m\) 个问题,其中 \(n\) 个答案为 yes,\(m\) 个答案为 no.每次你需要回答一个问题,然后得知这个 ...

  8. Solution -「AGC 013E」「AT 2371」Placing Squares

    \(\mathcal{Description}\)   Link.   给定一个长度为 \(n\) 的木板,木板上有 \(m\) 个标记点,第 \(i\) 个标记点距离木板左端点的距离为 \(x_i\ ...

  9. Solution -「AGC 003D」「AT 2004」Anticube

    \(\mathcal{Description}\)   Link.   给定 \(n\) 个数 \(a_i\),要求从中选出最多的数,满足任意两个数之积都不是完全立方数.   \(n\le10^5\) ...

随机推荐

  1. Linux上天之路(十四)之Linux数据处理

    主要内容 数据检索 数据排序 数据去重 重定向 1. 数据检索 常和管道协作的命令 – grep grep:用于搜索模式参数指定的内容,并将匹配的行输出到屏幕或者重定向文件中,常和管道协作的命令 – ...

  2. 利用Word2010制作流程图

    利用Word2010制作流程图 原文链接:https://www.toutiao.com/i6483034968225235469/ 一.页面和段落的设置 启动Word2010,打开一个空白文档,并切 ...

  3. CodeForces 519B A and B and Compilation Errors (超水题)

    这道题是超级水的,在博客上看有的人把这道题写的很麻烦. 用 Python 的话是超级的好写,这里就奉上 C/C++ 的AC. 代码如下: #include <cstdio> #includ ...

  4. xray与burp联动被动扫描

    最近也是刚实习了几天,看见带我的那位老哥在用xray,而且贼溜,所以我想写几篇关于xray的使用的文章 0x00 xray建立监听 在实际测试过程中,除了被动扫描,也时常需要手工测试.这里使用 Bur ...

  5. OSI/RM体系结构

    OSI/RM体系结构是第一个标准化的计算机网络体系结构.   它是针对广域网通信(也就是不同网络之间的通信)进行设计 的,将整个网络通信的功能划分为七个层次,由低到高分别是物理层(Physical L ...

  6. golang中的GOPATH使用和简单项目配置

    GOPATH 是 Go 语言的工作目录,他的值可以是一个目录路径,也可以是多个目录路径,每个目录都代表 go 语言的一个工作区. 我们开发 Golang 项目时,需要依赖一些别的代码包,这些包的存放路 ...

  7. gin中multipart/urlencoded表单

    package main import ( "github.com/gin-gonic/gin" ) func main() { router := gin.Default() r ...

  8. java继承成员变量特点

    1 /* 2 * 在子父类中,成员的特点体现. 3 * 1,成员变量. 4 * 2,成员函数. 5 * 3,构造函数. 6 */ 7 8 //1, 成员变量. 9 /* 10 * 当本类的成员和局部变 ...

  9. 在 Prim 算法中使用 pb_ds 堆优化

    在 Prim 算法中使用 pb_ds 堆优化 Prim 算法用于求最小生成树(Minimum Spanning Tree,简称 MST),其本质是一种贪心的加点法.对于一个各点相互连通的无向图而言,P ...

  10. JavaFx 软件重启功能实现

    原文地址: JavaFx 软件重启功能实现 | Stars-One的杂货小窝 本篇使用Kotlin在TornadoFx中实践,没有Java代码的示例,各位自行参考,思路已在本文中提及 实现思路 主要思 ...