考虑容斥,令$f(S)$为要求$\forall p\in S,p$可以作为起点的方案数,答案即$\sum_{S\subseteq[0,n)}(-1)^{|S|}f(S)$

关于计算$f(S)$,对于第$i$个机器人而言,$p$可以作为起点实际上即给出了$X_{i}$和$Y_{i}$每一位上的一种限制,限制共有四种(令两者分别为$x$和$y$,即$y=0,y=1,x=y$和$x\ne y$)

对每种限制预处理出第$i$个机器人以$p$为起点第$j$位上是否存在该限制,并用unsigned int存储,即可$o(n)$合并限制,进而对每一个位置分别求出满足此限制下的方案数,全部相乘即为$f(S)$

(另外需要注意如果会超出范围,仍存在全为空位的一组解)

预处理复杂度为$o(n^{2}m)$,求$f(S)$的复杂度为$o(nm)$,时间复杂度为$o(nm2^{n})$,无法通过

进一步的,预处理出子集并,再简单分类讨论即可快速求出方案数(一个unsigned int的2的位数可以将其前后的16位拆开分别处理),时间复杂度降为$o(m2^{n})$,仍无法通过

考虑优化,设第$i$个机器人有$r_{i}$个'R',那么若$r_{i}+\max_{x\in S}x\ge n$即会导致其对答案没有贡献

接下来,考虑暴力枚举$\max_{x\in S}x$并对其分类讨论:

1.若$\max_{x\in S}x<\lceil\frac{n}{2}\rceil$,直接暴力枚举$S$即可,时间复杂度为$o(m2^{\frac{n}{2}})$

2.若$\max_{x\in S}x\ge \lceil\frac{n}{2}\rceil$,那么若$r_{i}+x\ge n$其对答案也没有贡献,不需要考虑

换言之,此时即有$0\le r_{i}<x$,那么一个位置对答案是否有贡献仅取决于其之前$x$个格子的起点状态以及再之前是否存在起点(即要求相同)

由此,记录这些状态即可状压dp,通过预处理也可以做到$o((n^{2}+m)2^{\frac{n}{2}})$

综上,总复杂度为$o((n^{2}+m)2^{\frac{n}{2}})$,可以通过

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 35
4 #define M 1005
5 #define L (1<<16)
6 #define mod 1000000007
7 #define inv2 500000004
8 #define inv3 333333336
9 #define inv5 400000003
10 #define ll long long
11 #define ui unsigned int
12 int n,m,R,nn,ans,mi2[N],mi3[N],cnt[L],r[M];
13 char s[105];
14 ui o=1,lim[M][N][4],Lim[L][4];
15 int lowbit(int k){
16 return (k&(-k));
17 }
18 void get(int k){
19 int nn=(n+1>>1);
20 for(int i=0;i<nn;i++)memcpy(Lim[1<<i],lim[k][i],sizeof(lim[k][i]));
21 for(int S=1;S<(1<<nn);S++)
22 for(int i=0;i<4;i++)Lim[S][i]=(Lim[lowbit(S)][i]|Lim[S^lowbit(S)][i]);
23 }
24 namespace Subtask1{
25 int sum[L];
26 int count(ui k){
27 return cnt[k>>16]+cnt[k&(L-1)];
28 }
29 void calc(){
30 nn=(n+1>>1);
31 for(int S=1;S<(1<<nn);S++)sum[S]=1;
32 for(int i=1;i<=m;i++){
33 get(i);
34 for(int S=1;S<(1<<min(n-r[i],nn));S++){
35 ui p0=Lim[S][0],p1=Lim[S][1];
36 ui p2=Lim[S][2],p3=Lim[S][3];
37 ui P0=((p0&p1)|(p2&p3));
38 if (n<32)P0^=(o<<n)-1;
39 else P0^=(ui)(-1);
40 ui P1=((p0|p1)&(p2|p3)&P0);
41 sum[S]=(ll)mi2[count(P1)]*mi3[count(P0^P1)]%mod*sum[S]%mod;
42 }
43 }
44 for(int S=1;S<(1<<nn);S++)
45 if (cnt[S]&1)ans=(ans+sum[S])%mod;
46 else ans=(ans-sum[S]+mod)%mod;
47 }
48 }
49 namespace Subtask2{
50 int id[M],g[L][2],f[2][L][2];
51 bool cmp(int x,int y){
52 return r[x]<r[y];
53 }
54 void calc(){
55 for(int i=1;i<=m;i++)id[i]=i;
56 sort(id+1,id+m+1,cmp);
57 nn=(n>>1);
58 for(int S=0;S<(1<<nn);S++)g[S][0]=g[S][1]=1;
59 for(int x=n-1,k=1;x>=n-nn;x--){
60 while ((k<=m)&&(r[id[k]]+x<n)){
61 get(id[k]);
62 for(int S=0;S<(1<<nn);S++){
63 int p0=((Lim[S][0]>>nn-1)&1),p1=((Lim[S][1]>>nn-1)&1);
64 int p2=((Lim[S][2]>>nn-1)&1),p3=((Lim[S][3]>>nn-1)&1);
65 if ((p0&p1)||(p2&p3))continue;
66 if ((p0|p1)&&(p2|p3))g[S][0]=2*g[S][0]%mod;
67 else{
68 if (p0|p1|p2|p3)g[S][0]=3LL*g[S][0]%mod;
69 else g[S][0]=5LL*g[S][0]%mod;
70 }
71 p2=1;
72 if ((p0&p1)||(p2&p3))continue;
73 if ((p0|p1)&&(p2|p3))g[S][1]=2*g[S][1]%mod;
74 else g[S][1]=3LL*g[S][1]%mod;
75 }
76 k++;
77 }
78 memset(f[0],0,sizeof(f[0]));
79 f[0][0][0]=1;
80 for(int i=0;i<x;i++){
81 int ii=(i&1);
82 memset(f[ii^1],0,sizeof(f[ii^1]));
83 for(int S=0;S<(1<<nn);S++){
84 int p=(S&1),SS=(S>>1);
85 f[ii^1][SS][p]=(f[ii^1][SS][p]+(ll)g[SS][1]*f[ii][S][0])%mod;
86 f[ii^1][SS][1]=(f[ii^1][SS][1]+(ll)g[SS][1]*f[ii][S][1])%mod;
87 SS|=(1<<nn-1);
88 f[ii^1][SS][p]=(f[ii^1][SS][p]-(ll)g[SS][1]*f[ii][S][0]%mod+mod)%mod;
89 f[ii^1][SS][1]=(f[ii^1][SS][1]-(ll)g[SS][1]*f[ii][S][1]%mod+mod)%mod;
90 }
91 }
92 for(int S=0;S<(1<<nn);S++){
93 int p=(S&1),SS=((S>>1)|(1<<nn-1)),s=f[x&1][S][0];
94 for(int j=x;j<n;j++){
95 s=(ll)s*g[SS][p]%mod;
96 p|=(SS&1),SS>>=1;
97 }
98 ans=(ans+s)%mod;
99 SS=((S>>1)|(1<<nn-1)),s=f[x&1][S][1];
100 for(int j=x;j<n;j++){
101 s=(ll)s*g[SS][1]%mod;
102 SS>>=1;
103 }
104 ans=(ans+s)%mod;
105 }
106 }
107 }
108 }
109 int main(){
110 mi2[0]=mi3[0]=1;
111 for(int i=1;i<N;i++){
112 mi2[i]=2*mi2[i-1]%mod;
113 mi3[i]=3LL*mi3[i-1]%mod;
114 }
115 for(int i=1;i<L;i++)cnt[i]=cnt[i^lowbit(i)]+1;
116 scanf("%d%d",&n,&m);
117 for(int i=1;i<=m;i++){
118 scanf("%s",s);
119 for(int j=0;s[j];j++)
120 if (s[j]=='R')r[i]++;
121 for(int j=0;j<n-r[i];j++){
122 for(int k=0;k<j;k++)lim[i][j][2]|=(o<<k);
123 for(int k=j+r[i]+1;k<n;k++)lim[i][j][2]|=(o<<k);
124 int pos=j,lst=2;
125 for(int k=0;s[k];k++){
126 if (s[k]=='R'){
127 lim[i][j][lst]|=(o<<pos);
128 pos++,lst=2;
129 }
130 else{
131 if (s[k]=='*')lst^=1;
132 else lst=s[k]-'0';
133 }
134 }
135 lim[i][j][lst]|=(o<<pos);
136 }
137 }
138 Subtask1::calc();
139 Subtask2::calc();
140 printf("%d\n",ans);
141 return 0;
142 }

[luogu7740]机器人游戏的更多相关文章

  1. Solution -「NOI 2021」「洛谷 P7740」机器人游戏

    \(\mathcal{Description}\)   Link.   自己去读题面叭~ \(\mathcal{Solution}\)   首先,参悟[样例解释 #2].一种暴力的思路即为钦定集合 \ ...

  2. 玩家福音:10款最佳Linux免费游戏

    “我能在Linux平台上游戏吗?”这类疑问正困扰游戏玩家,那么答案就是“快去Linux平台吧!”.开源组织一直以来坚持不懈为Linux操作系统开发不同类型的游戏,在Linux平台下的游戏完全不亚于其他 ...

  3. 开源玩家福利:十大Linux免费游戏

    假如当你考虑从Windows平台迁移至Linux平台时,“我能在Linux平台上游戏吗?”这类疑问正困扰着你,那么对此这有一个答案就是“快去Linux平台吧!”.感谢开源组织一直以来坚持不懈为Linu ...

  4. Unity3d入门 - 关于unity工具的熟悉

    上周由于工作内容较多,花在unity上学习的时间不多,但总归还是学习了一些东西,内容如下: .1 根据相关的教程在mac上安装了unity. .2 学习了unity的主要的工具分布和对应工具的相关的功 ...

  5. Android 7.0真实上手体验

    Android 7.0真实上手体验 Android 7.0的首个开发者预览版发布了,支持的设备只有Nexus6.Nexus 5X.Nexus 6P.Nexus 9.Nexus Player.Pixel ...

  6. 2021NOI同步赛

    \(NOI\) 网上同步赛 明白了身为菜鸡的自己和普通人的差距 DAY1 \(T1\) 轻重边 [题目描述] 小 W 有一棵 \(n\) 个结点的树,树上的每一条边可能是轻边或者重边.接下来你需要对树 ...

  7. (NO.00003)iOS游戏简单的机器人投射游戏成形记(十八)

    在游戏中制作手臂瞄准线,也就是所谓的辅助延长线.玩台球游戏的童鞋应该可以了解. 按道理来说,延长线是一个物理实体,遇到物理刚体应该会发生反弹行为,这个符合实际游戏逻辑. 但是这里为了简单,只是做一条& ...

  8. (NO.00003)iOS游戏简单的机器人投射游戏成形记(九)

    现在按住手臂可以非常自然和舒服的旋转了,丝般顺滑:移动停止,旋转立即停止,没有什么惯性影响了. 以上一共介绍了2中旋转方式,到底采用哪种方式呢?其实看实际游戏的需求和个人的喜好了.本猫在Level中添 ...

  9. (NO.00003)iOS游戏简单的机器人投射游戏成形记(三)

    接下来我们建立机器人对象. 在Sprites文件夹中新建Robot.ccb文件,类型为Node. 打开SpriteBuilder的Tileless View将机器人身体和手臂拖入根节点,调整好相对的位 ...

随机推荐

  1. Codeforces Round #747 (Div. 2)

    比赛地址 A(水题) 题目链接 题目: 给出指定\(n\),求解出一段区间\([l,r]\)使得\(\sum\limits_{i=l}^ri=n\) 解析: 从点0,1两点作为起点分别向左右延伸长度, ...

  2. keeplived高可用配置

    前提:关闭防火墙,关闭selinux 1.主备配置 主 vim keeplived-lb01.confglobal_defs { router_id LVS_01 } vrrp_instance VI ...

  3. t-SNE算法

    t-SNE 算法 前言 t-SNE(t-distributed stochastic neighbor embedding) 是用于降维的一种机器学习算法,由 Laurens van der Maat ...

  4. 从零入门 Serverless | 使用 Spot 低成本运行 Job 任务

    作者 | 代志锋(云果)  阿里云技术专家 本文整理自<Serverless 技术公开课>,点击链接即可免费听课:https://developer.aliyun.com/learning ...

  5. 题解 [AGC017C] Snuke and Spells

    题目传送门 Description 有 \(n\) 个球排在一起,每个球有颜色 \(a_i\),若当前有 \(k\) 个球,则会将所有 \(a_i=k\) 的球删掉.有 \(m\) 次查询,每次将 \ ...

  6. NX CAM 读取加工参数

    '取加工几何试图程序组 Function GetGemoGroup_Name(ByVal camObjectTag As NXOpen.Tag) As String Dim theGemoGroupT ...

  7. kafka应用讲解及应用场景(三)

    一. 验证 1.进入bin目录 cd bin 2.ls查看脚本 会发现下面有很多脚本文件,由于我是要创建一个topic所有直接打开kafka-topics.sh脚本查看命令 打开脚本后发现里面有很多命 ...

  8. Win10 配置JDK1.8 (JDK 8)环境变量

    JDK的安装: 1. JDK安装过程中,一般X掉公共JRE,因为JDK包含了JRE:     环境变量的配置: 1. 打开环境变量,编辑系统变量,新建: 变量名:JAVA_HOME 变量值:D:\so ...

  9. SharkCTF2021 bybypass&baby_phpserialize题记

    (国庆褪10天了 先水一篇) bybypass: payload:?anime_is_bae=hehellotherehoomanllotherehooman baby_phpserialize ro ...

  10. Java:NIO 学习笔记-2

    Java:NIO 学习笔记-2 上一篇 NIO 学习笔记-1 看了 尚硅谷 的相应教程,此处又对比看了 黑马程序员 的课程 JAVA通信架构I/O模式,做了相应的笔记 前言 在 Java 的软件设计开 ...