P7740-[NOI2021]机器人游戏【dp,bitset】

1|0正题

题目链接:https://www.luogu.com.cn/problem/P7740


1|1题目描述

题目大意摸了

小 R 有 m1m1000)个机器人和 m 张纸带,第 i1im)个机器人负责对第 i 张纸带进行操作。对于每张纸带,它们都被从左到右分成了 n1n32)个格子,依次编号为 0,1,,n1。每个格子有 3 种状态:1. 格子上写有数字 0;2. 格子上写有数字 1;3. 格子是一个空格子。

在任意时刻,机器人必须站在纸带上的一个格子中。在设定好机器人在纸带上的初始位置后,第 i 个机器人会依次执行预先设定的操作序列 Si,操作由 R01* 四种字符组成,其中:

  1. R 表示机器人向右走一格,如果右边没有格子,则机器人会原地爆炸;
  2. 0 表示如果机器人所在格子非空,则将该格子上的数字改为 0,否则不修改;
  3. 1 表示如果机器人所在格子非空,则将该格子上的数字改为 1,否则不修改;
  4. * 表示如果机器人所在格子非空,则将格子上的数字 x 改为 1x,否则不修改。

i 张纸带的状态可以用一个长度为 n 的序列表示,每个元素为 01-(空格子),依次表示其每个格子的状态。第 i 张纸带的初始状态称为机器人 i 的输入 Xi,操作执行完成后纸带的状态称为机器人 i 的输出 Yi。注意,如果机器人爆炸了,那么这个机器人就没有输出。

可以发现,如果一个格子为空,那么机器人永远不会修改它。所以每个机器人都有如下特性:如果第 i 个机器人所在的纸带上的所有格子都为空,那么它就不会执行任何操作,它的输出即为所有格子都为空。

现在小 R 给定了每一个机器人的输入 Xi(即每张纸带的初始状态)以及目标输出 Yi。小 R 希望小 D 找到一个位置 p0p<n),使得所有机器人都能以其所在纸带的第 p 个格子为初始位置,在不爆炸的情况下执行完所有操作,并且满足第 i 个机器人的输出为 Yi

小 D 花了几毫秒解决了问题,现在他想知道,有多少个输入和输出的组合方式使得上述问题有解,即有多少种为每个机器人设定输入 X0,X1,,Xm1 和目标输出 Y0,Y1,,Ym1 的方式,使得至少存在一个位置 p0p<n),使得所有机器人都能以其所在纸带的第 p 个格子为起点,在不爆炸的情况下执行完所有操作,且满足第 i 个机器人的输出为 Yi。请你帮助小 D 解决这个问题,由于最终的答案可能很大,请你输出答案对 109+7 取模后的余数。

两个组合方式不同当且仅当,存在至少一个机器人,它的输入或是目标输出在两个方式中不同。

对于所有测试点:1n321m10001|Si|100

测试点编号 n m 特殊限制
12 1 1
3 8 1
4 16 1
56 32 1
7 16 5
810 32 5
1112 16 1000
1315 32 1000 A
1621 32 1000 B
2225 32 1000

特殊限制 A:操作序列中不存在 R

特殊限制 B:每个操作序列中,R 的数量至多 15 个。


1|2解题思路

先考虑n比较小的情况。对于每个机器人,我们可以把它的操作表示成相对于起点位置的4种状态:必定为0/1,与之前相同/不同。

然后至少有一个合法的x的限制我们可以考虑容斥,钦定一些合法的位置,那么对于纸带的一个位置来说它的限制最多只有四种,我们对于不同的情况这个位置不同的起始状态对应同样数量的中止状态。

但是我们暴力枚举合法位置的复杂度是O(2n)的,考虑能不能优化。

因为这个n=32,看上去就很像折半,所以我们考虑一下怎么折半。

我们会发现因为最大位置不能超出纸条,所以设一个机器人最远的操作位置是len,那么对于这个机器人来说合法的x就不能超过nlen。而如果len比较小,那么一个位置能影响到后面的位置就不多,我们可以设fi,S表示目前做到i,对于后面的限制目前是S时前面已经确定了限制的位置的答案。

然后所有的机器人同时做就可以了。

然后再处理限制的时候用bitset优化一下就行了。

时间复杂度:O(2nnmω)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<bitset> #define ll long long using namespace std; const ll N=34,M=1100,P=1e9+7; ll n,m,pw2[M],pw3[M],v[M][N],c[M]; ll ans,num,f[N][1<<17][2]; vector<ll> q[N];char s[N*3]; bitset<M> all,v1,v2,u_[N],u[4][N],F[1<<17][4]; signed main() { scanf("%lld%lld",&n,&m); pw2[0]=pw3[0]=1; for(ll i=1;i<=m;i++)pw2[i]=pw2[i-1]*2ll%P,pw3[i]=pw3[i-1]*3ll%P; for(ll i=0;i<m;i++){ scanf("%s",s+1);ll len=strlen(s+1),cr=0; for(ll j=1;j<=len;j++){ if(s[j]=='R')v[i][c[i]]=cr,cr=0,c[i]++; else if(s[j]=='0')cr=2; else if(s[j]=='1')cr=3; else if(s[j]=='*')cr^=1; } v[i][c[i]]=cr;q[c[i]].push_back(i); all.set(i); } ans=1; for(ll i=1;i<=n*m;i++)ans=ans*3ll%P; for(ll r=n;r>=0;r--){ for(ll i=0;i<q[n-r].size();i++){ for(ll j=0;j<n+2;j++)u[v[q[n-r][i]][j]][j].set(q[n-r][i]); for(ll j=c[q[n-r][i]]+1;j<n+2;j++)u_[j].set(q[n-r][i]); } f[0][0][0]=1;num+=q[n-r].size(); for(ll i=1;i<=r;i++){ ll MS=(1<<min(i,n-r+1)),MT=(1<<min(i-1,n-r+1)); for(ll s=0;s<MS;s++)f[i][s][0]=f[i][s][1]=0; for(ll z=0;z<2;z++) for(ll s=0;s<MT;s++){ ll _z=z|(s*2>=MS); if(i<r)(f[i][(s<<1)&(MS-1)][_z]+=f[i-1][s][z])%=P; (f[i][(s<<1|1)&(MS-1)][_z]+=P-f[i-1][s][z])%=P; } for(ll z=0;z<2;z++){ ll lr=z|(i<r); for(ll s=0;s<min(n-r+1,i);s++){ for(ll j=lr;j<4;j++)F[1<<s][j]=u[j][s]; if(!lr)F[1<<s][0]|=u_[s]; } for(ll s=0;s<MS;s++){ if(s!=(s&-s)){ for(ll k=lr;k<4;k++) F[s][k]=F[s&-s][k]|F[s-(s&-s)][k]; } if(lr){ v1=F[s][1]|(F[s][2]&F[s][3]); v2=(F[s][2]|F[s][3])&(v1^all); } else{ v1=(F[s][0]&F[s][1])|(F[s][2]&F[s][3]); v2=(F[s][0]|F[s][1])&(F[s][2]|F[s][3])&(v1^all); } ll X=v1.count(),Y=v2.count(); (f[i][s][z]=f[i][s][z]*pw2[Y]%P*pw3[num-X-Y]%P)%=P; } } } ll lim=min(n-r+1,r),MS=1<<lim; for(ll z=0;z<2;z++) for(ll i=1;i<=n-r;i++){ for(ll s=0;s<lim;s++){ for(ll j=z;j<4;j++)F[1<<s][j]=u[j][s+i]; } for(ll s=0;s<MS;s++){ if(s!=(s&-s)){ for(ll k=z;k<4;k++) F[s][k]=F[s&-s][k]|F[s-(s&-s)][k]; } if(z){ v1=F[s][1]|(F[s][2]&F[s][3]); v2=(F[s][2]|F[s][3])&(v1^all); } else{ v1=(F[s][0]&F[s][1])|(F[s][2]&F[s][3]); v2=(F[s][0]|F[s][1])&(F[s][2]|F[s][3])&(v1^all); } ll X=v1.count(),Y=v2.count(); (f[r][s][z]=f[r][s][z]*pw2[Y]%P*pw3[num-X-Y]%P)%=P; } } for(ll z=0;z<2;z++) for(ll s=0;s<MS;s++) (ans+=P-f[r][s][z])%=P; } printf("%lld\n",ans); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/16467508.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2021-07-11 P7717-「EZEC-10」序列【Trie】
点击右上角即可分享
微信分享提示