Solution -「AGC 016F」Games on DAG
\(\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{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}\)
/* Clearink */
#include <cstdio>
#define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
#define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i )
const int MAXN = 15, MAXM = MAXN * ( MAXN - 1 ) >> 1, MOD = 1e9 + 7;
int n, m, pwr[MAXM + 5], conc[1 << MAXN][MAXN], f[1 << MAXN];
bool adj[MAXN + 5][MAXN + 5];
inline int mul( const long long a, const int b ) { return a * b % MOD; }
inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int add( int a, const int b ) { return ( a += b ) < MOD ? a : a - MOD; }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
int main() {
scanf( "%d %d", &n, &m ), pwr[0] = 1;
rep ( i, 1, m ) {
pwr[i] = add( pwr[i - 1], pwr[i - 1] );
int u, v; scanf( "%d %d", &u, &v );
adj[u - 1][v - 1] = true;
}
rep ( S, 1, ( 1 << n ) - 1 ) {
int v = 0; for ( ; !( S >> v & 1 ); ++v );
rep ( u, 0, n - 1 ) conc[S][u] = conc[S ^ 1 << v][u] + adj[u][v];
}
rep ( S, 0, ( 1 << n ) - 1 ) if ( ( S & 3 ) == 3 ) {
f[S] = 1;
for ( int T = S & ( S - 1 ); T; T = ( T - 1 ) & S ) {
if ( T & 1 && T & 2 ) {
int coe = 1;
rep ( u, 0, n - 1 ) if ( S >> u & 1 ) {
if ( T >> u & 1 ) {
coe = mul( coe, pwr[conc[S ^ T][u]] - 1 );
} else {
coe = mul( coe, pwr[conc[T][u]] );
}
}
addeq( f[S], mul( coe, f[T] ) );
} else if ( !( T & 1 || T & 2 ) ) {
int coe = 1;
rep ( u, 0, n - 1 ) if ( S >> u & 1 ) {
if ( T >> u & 1 ) {
coe = mul( coe,
mul( pwr[conc[S ^ T][u]] - 1, pwr[conc[T][u]] ) );
} else {
coe = mul( coe, pwr[conc[T][u]] );
}
}
addeq( f[S], coe );
}
}
}
printf( "%d\n", sub( pwr[m], f[( 1 << n ) - 1] ) );
return 0;
}
Solution -「AGC 016F」Games on DAG的更多相关文章
- Solution -「AGC 036D」「AT 5147」Negative Cycle
\(\mathcal{Descriprtion}\) Link. 在一个含 \(n\) 个结点的有向图中,存在边 \(\lang i,i+1,0\rang\),它们不能被删除:还有边 \(\l ...
- Solution -「AGC 026D」Histogram Coloring
\(\mathcal{Description}\) Link. 有 \(n\) 列下底对齐的方格纸排成一行,第 \(i\) 列有 \(h_i\) 个方格.将每个方格染成黑色或白色,求使得任意完 ...
- Solution -「AGC 004E」「AT 2045」Salvage Robots
\(\mathcal{Description}\) Link. 有一个 \(n\times m\) 的网格.每个格子要么是空的,要么有一个机器人,要么是一个出口(仅有一个).每次可以命令所有机 ...
- Solution -「AGC 012F」「AT 2366」Prefix Median
\(\mathcal{Description}\) Link. 给定序列 \(\{a_{2n-1}\}\),将 \(\{a_{2n-1}\}\) 按任意顺序排列后,令序列 \(b_i\) 为前 ...
- Solution -「AGC 010C」「AT 2304」Cleaning
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的无根树,点有点权,每次选择两个不同的叶子,使它们间的简单路径的所有点权 \(-1\),问能否将所有点 ...
- Solution -「AGC 019E」「AT 2704」Shuffle and Swap
\(\mathcal{Description}\) Link. 给定 \(01\) 序列 \(\{A_n\}\) 和 \(\{B_n\}\),其中 \(1\) 的个数均为 \(k\).记 \( ...
- Solution -「AGC 019F」「AT 2705」Yes or No
\(\mathcal{Description}\) Link. 有 \(n+m\) 个问题,其中 \(n\) 个答案为 yes,\(m\) 个答案为 no.每次你需要回答一个问题,然后得知这个 ...
- Solution -「AGC 013E」「AT 2371」Placing Squares
\(\mathcal{Description}\) Link. 给定一个长度为 \(n\) 的木板,木板上有 \(m\) 个标记点,第 \(i\) 个标记点距离木板左端点的距离为 \(x_i\ ...
- Solution -「AGC 003D」「AT 2004」Anticube
\(\mathcal{Description}\) Link. 给定 \(n\) 个数 \(a_i\),要求从中选出最多的数,满足任意两个数之积都不是完全立方数. \(n\le10^5\) ...
随机推荐
- 微信小程序css继承
在微信小程序里写的全局样式,pages里的组件是可以继承的,但是components里只能继承font和color属性.
- Rust学习(一)
为什么学习Rust 最近在看Linux相关新闻的时候,看到了Linux内核正在将Rust集成至内核内的消息,且越来越多的嵌入式开发可以使用Rust编程.以往笔者的技术栈只有 C语言 ,C++也只是浅尝 ...
- git 重置密码后,本地电脑需要修改git密码
查看用户名git config user.name 查看密码git config user.password 查看邮箱git config user.email 修改密码git config --gl ...
- 云计算实验二 Docker实验-mysql、tomcat、sqlserver、redis、oracle、mongo安装
mysql安装 下载镜像 docker pull mysql 查看镜像 docker images|grep mysql 创建启动容器 docker run --name mysqlserver -v ...
- 小记录:flask的DEBUG开关
请求站点的如下位置: http://www.ahfu.com/ahfuzhang/?debugger=yes&cmd=resource&f=style.css 居然正常范围了CSS文件 ...
- Servlet Filter(过滤器)
Servlet Filter 又称 Servlet 过滤器,它是在 Servlet 2.3 规范中定义的,能够对 Servlet 容器传给 Web 资源的 request 对象和 response 对 ...
- MySQL环境变量配置方法
MySQL配置方法 下载免安装版本的MySQL数据库,大家根据自己的开发环境下载对应版本的数据库,我在此举例的是Windows系统下的配置方法,下载地址如下: https://dev.mysql.co ...
- golang中锁
一.什么场景下需要用到锁当程序中就一个线程的时候,是不需要加锁的,但是通常实际的代码不会只是单线程,有可能是多个线程同时访问公共资源,所以这个时候就需要用到锁了,那么关于锁的使用场景主要涉及到哪些呢? ...
- 只要一行代码,实现五种 CSS 经典布局
常用的页面布局,其实就那么几个.下面我会介绍5个经典布局,只要掌握了它们,就能应对绝大多数常规页面. 这几个布局都是自适应的,自动适配桌面设备和移动设备.代码实现很简单,核心代码只有一行,有很大的学习 ...
- 测试udp端口
yum -y install nc 在a机器上执行: nc -ul 1080 在b机器上执行:nc -u 服务器ip 1080 a机器可以接收到报文则代表端口正常.