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)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
随机推荐
- 在 CentOS 7 上安装和配置 Puppet
1 准备 2台 centos7 (master/server:192.168.1.103 agent/client:192.168.1.106) 分别添加puppet自定义仓库 https://yum ...
- antd-vue中的form表单label标签for导致点击文字触发输入框解决方案
<a-form-item :label="label+'图片'" :label-col="{ span: 2 }" :wrapper-col=" ...
- antd的table组件设置Column的width列宽度不生效问题
超长连续字段(长数字和长单词) 破坏表格布局的问题(即使你指定了列的宽度也会被挤开),之前组件内默认加过 word-break: break-word; 去纠正此类布局,又会引起其他的问题. 所以最好 ...
- Android官方文档翻译 四 1.2Running Your App
Running Your App If you followed the previous lesson to create an Android project, it includes a def ...
- 顺序表-Go语言实现
简单理解就是数组: 优缺点及使用场景 优点: 随机访问,在O(1)时间内找到第i个元素: 数据表中的数据是连续存放的,因此只要知道数据表中第一个元素的地址,那么后面的数据元素的地址就可以马上算出来. ...
- Solon Web 开发,六、过滤器、处理、拦截器
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- NPOI处理Excel
using NPOI; using NPOI.XSSF.UserModel; using NPOI.SS.UserModel; using NPOI.HSSF.UserModel; NPOI.SS.U ...
- 【刷题-LeetCode】123 Best Time to Buy and Sell Stock III
Best Time to Buy and Sell Stock III Say you have an array for which the ith element is the price of ...
- 【笔记】golang中使用protocol buffers的底层库直接解码二进制数据
背景 一个简单的代理程序,发现单核QPS达到2万/s左右就上不去了,40%的CPU消耗在pb的decode/encode上面. 于是我想,对于特定的场景,直接从[]byte中取出字段,而不用完全的把整 ...
- 【Vulnhub靶场】EMPIRE: BREAKOUT
环境准备 下载靶机,导入到vmware里面,这应该不用教了吧 开机可以看到,他已经给出了靶机的IP地址,就不用我们自己去探测了 攻击机IP地址为:192.168.2.15 靶机IP地址为:192.16 ...