Solution -「NOI 2021」「洛谷 P7740」机器人游戏
\(\mathcal{Description}\)
Link.
自己去读题面叭~
\(\mathcal{Solution}\)
首先,参悟【样例解释 #2】。一种暴力的思路即为钦定集合 \(S\) 内的位置都合法,容斥计数。其中对于每条纸带的每个位置,有三种情况(令 _ 为“保持不变”,注意没有被机器人经过的位置都有这种修改):
- 同时存在
_和*;或者同时存在0和1:只能为空,方案数为 \(1\); - 否则,存在(
_或*)且存在(0或1):只能为空或01中的一个,方案数为 \(2\); - 否则,方案数为 \(3\)。
暴力做的复杂度是 \(\mathcal O(2^nn^am^b)\),\(a,b\) 看细节实现,不太可观。
尝试钦定最后一个在 \(S\) 中的位置为 \(r\),那么所有修改长度大于 \(n-r+1\) 的机器人所在的纸带都必须全空。在此限制下带着容斥系数状压 DP,令 \(f(i,S)\) 表示考虑了纸带的位置 \(i\),前若干个位置的选择情况为 \(S\),注意此处 \(|S|\le2^{\min\{i,n-r\}}=\mathcal O(2^{n/2})\),转移时可以 \(\mathcal O(nm)\) 暴力计算当前位置的贡献,得到了 \(\mathcal O(2^{n/2}nm)\) 的算法。
顺带,注意到统计当前位置贡献时可以描述为形如“有多少个机器人的修改序列中,下标属于 \(S\) 的位置上存在 _/*/0/1”,可以用 std::bitset 优化。最终复杂度为 \(\mathcal O(\frac{2^{n/2}nm}{\omega})\)。
\(\mathcal{Code}\)
/*~Rainybunny~*/
#include <bitset>
#include <cstdio>
#include <cassert>
#include <cstring>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
typedef unsigned long long ULL;
const int MAXN = 32, MAXM = 1e3, MOD = 1e9 + 7;
int n, m, pw2[MAXM + 5], pw3[MAXM + 5];
inline int imin( const int a, const int b ) { return a < b ? a : b; }
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int mul( const int a, const int b ) { return int( 1ll * a * b % 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 ); }
struct Robot {
int len, val[MAXN + 5];
inline int operator [] ( const int k ) const {
return k <= len ? val[k] : 0;
}
inline void read() {
static char str[105]; scanf( "%s", str );
val[len = 1] = 0;
for ( int i = 0; str[i]; ++i ) {
if ( str[i] == 'R' ) val[++len] = 0;
else if ( str[i] == '0' ) val[len] = 1;
else if ( str[i] == '1' ) val[len] = 2;
else val[len] = 3 - val[len];
}
}
} rbt[MAXM + 5];
inline int solve( const int r ) {
static int f[2][1 << 17][2];
static std::bitset<MAXM + 5> sig[MAXN + 5][4], g[1 << 17][4];
int allc = 0;
rep ( i, 0, n - 1 ) rep ( j, 0, 3 ) sig[i][j].reset();
rep ( i, 1, m ) if ( rbt[i].len <= n - r + 1 ) {
++allc;
rep ( j, 0, n - 1 )
sig[j][rbt[i][j + 1]].set( i );
}
rep ( i, 0, imin( n - r, r ) ) rep ( j, 0, 3 ) {
g[1 << i][j] = sig[i][j];
}
rep ( S, 1, ( 1 << imin( n - r, r ) << 1 ) - 1 ) if ( S & ( S - 1 ) ) {
rep ( i, 0, 3 ) {
g[S][i] = g[S ^ ( S & -S )][i] | g[S & -S][i];
}
}
auto calc = [&]( const bool sty, const ULL S )->int {
static std::bitset<MAXM + 5> x, y;
x = ( sty ? g[S][3] : g[S][0] & g[S][3] ) | ( g[S][1] & g[S][2] );
y = ~x & ( sty ? g[S][1] | g[S][2] :
( g[S][0] | g[S][3] ) & ( g[S][1] | g[S][2] ) );
int t = y.count();
return mul( pw2[t], pw3[allc - t - x.count()] );
};
memset( f[0], 0, sizeof f[0] ), f[0][0][0] = 1;
for ( int i = 0, sta = 0; i < r; ++i, sta ^= 1 ) {
memset( f[!sta], 0, sizeof f[!sta] );
rep ( S, 0, ( 1 << imin( i, n - r ) ) - 1 ) {
ULL T = ULL( S ) << 1ull & ( ( 1ull << n >> r ) - 1 );
bool flg = ULL( S ) << 1ull << r >> n & 1ull;
rep ( t, 0, 1 ) {
int cur = f[sta][S][t]; f[sta][S][t] = 0;
if ( !cur ) continue;
subeq( f[!sta][r == n ? 0 : T | 1][t || flg || r == n],
mul( cur, calc( t || i + 1 < r, S << 1 | 1 ) ) );
if ( i + 1 < r ) {
addeq( f[!sta][T][t || flg],
mul( cur, calc( 1, S << 1 ) ) );
}
}
}
}
int ret = 0;
rep ( t, 0, 1 ) {
for ( int d = 1, sta = r & 1; d <= n - r; ++d, sta ^= 1 ) {
rep ( i, 0, imin( r, n - r ) - 1 ) {
rep ( j, t, 3 ) g[1 << i][j] = sig[i + d][j];
}
rep ( S, 0, ( 1 << imin( r, n - r ) ) - 1 ) {
if ( S & ( S - 1 ) ) {
rep ( j, t, 3 ) {
g[S][j] = g[S ^ ( S & -S )][j] | g[S & -S][j];
}
}
f[!sta][S][t] = mul( f[sta][S][t], calc( t, S ) );
f[sta][S][t] = 0;
}
}
rep ( S, 0, ( 1 << imin( r, n - r ) ) - 1 ) {
addeq( ret, f[n & 1][S][t] );
}
}
return ret;
}
int main() {
// freopen( "robot.in", "r", stdin );
// freopen( "robot.out", "w", stdout );
scanf( "%d %d", &n, &m );
pw2[0] = pw3[0] = 1;
rep ( i, 1, m ) {
rbt[i].read();
pw2[i] = mul( 2, pw2[i - 1] ), pw3[i] = mul( 3, pw3[i - 1] );
}
int ans = 0;
rep ( i, 1, n ) subeq( ans, solve( i ) );
printf( "%d\n", ans );
return 0;
}
Solution -「NOI 2021」「洛谷 P7740」机器人游戏的更多相关文章
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- 洛谷P1118 数字三角形游戏
洛谷1118 数字三角形游戏 题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直 ...
- 洛谷P1274-魔术数字游戏
Problem 洛谷P1274-魔术数字游戏 Accept: 118 Submit: 243Time Limit: 1000 mSec Memory Limit : 128MB Probl ...
- 洛谷 P4012 深海机器人问题【费用流】
题目链接:https://www.luogu.org/problemnew/show/P4012 洛谷 P4012 深海机器人问题 输入输出样例 输入样例#1: 1 1 2 2 1 2 3 4 5 6 ...
- 洛谷P1288 取数游戏II(博弈)
洛谷P1288 取数游戏II 先手必胜的条件需要满足如下中至少 \(1\) 条: 从初始位置向左走到第一个 \(0\) 的位置,经过边的数目为偶数(包含 \(0\) 这条边). 从初始位置向右走到第一 ...
- Solution -「JSOI 2019」「洛谷 P5334」节日庆典
\(\mathscr{Description}\) Link. 给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的). \(|S|\le3\time ...
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- Solution -「POI 2010」「洛谷 P3511」MOS-Bridges
\(\mathcal{Description}\) Link.(洛谷上这翻译真的一言难尽呐. 给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...
- Solution -「APIO 2016」「洛谷 P3643」划艇
\(\mathcal{Description}\) Link & 双倍经验. 给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
随机推荐
- 第10组 Alpha冲刺 (2/6)
1.1基本情况 ·队名:今晚不睡觉 ·组长博客:https://www.cnblogs.com/cpandbb/ ·作业博客:https://edu.cnblogs.com/campus/fzu/FZ ...
- httprunner3.x全网最详细教程
一.所需环境 wiindows10以上 python3.6以上 httprunner3.1.6(最新版本) pycharm社区版 二.安装httprunner 1.卸载旧版本 卸载之前版本的命令为:p ...
- 【Java】流程控制
文章目录 流程控制 一.用户交互scanner 1.1 Scanner对象 1.2 Scanner进阶使用 二.顺序结构 三.选择结构 3.1 if单选择结构 3.2 if双选择结构 3.3 if多选 ...
- Netlib文件转化为mps文件
Netlib文件转化为mps文件 简单方法1 下载并执行: git clone https://github.com/mtanneau/Netlib_experiments.git cd Netlib ...
- 网络编程-跨域资源共享 CORS
目录 1.什么是同源策略? 2.跨域资源共享 CORS 3.预检请求 4.CORS相关字段 5.Golang实现跨域 6.参考资料 1.什么是同源策略? 如果两个 URL 的 protocol.por ...
- 【代码分享】用redis+lua实现多个集合取交集并过滤,类似于: select key from set2 where key in (select key from set1) and value>=xxx
redis中的zset结构可以看成一个个包含数值的集合,或者认为是一个关系数据库中用列存储方式存储的一列. 需求 假设我有这样一个数据筛选需求,用SQL表示为: select key from set ...
- Python实现查询12306火车票信息
例子来源于马哥的公众号,看了几遍,有些地方存在些疑问,然后就自己查找些资料,重写的一下,但是对于获取到的信息,并不能有效的解析出来,而且对于中文字符处理,并不是很好,请大神指教下!谢过! 1.接口设置 ...
- java继承子类实例化过程(细节解释)
1 package face_08; 2 class Fu{ 3 Fu(){ 4 super(); 5 show(); 6 return; 7 } 8 void show() { 9 System.o ...
- IoC容器-Bean管理注解方式(注入属性@Autowired和Qualifier)
基于注解方式实现属性注入 (1)@Autowired:根据属性类型进行自动装配 第一步 把 service 和 dao 对象创建,在service 和 dao 类添加创建对象注解 第二步 在servi ...
- AWS 模拟题知识点总结!
一 题库的地址 https://www.lleicloud.com/index.php/aws-certified-saa-c01-practice-questions-c6-01/ 二 总结的知识点 ...