首先拓扑排序,并将障碍点按拓扑序平均分成两半。

那么一条$0$到$1$的路径一定是形如:

$0$->前一半点->后一半点->第一个后一半障碍点->后一半点->$1$。

对于两边分别暴力枚举所有情况,设$f[i]$表示$0$出发到达$i$,且到$i$之前不经过任意一个后一半障碍点到达$i$的路径数;$g[i]$表示从$i$出发到$1$的路径数。

那么枚举第一个后一半障碍点(或者是$1$),需要满足$f==1$且$g==1$,于是用FWT加速计算这个与卷积即可。

时间复杂度$O(2^\frac{Y}{2}(N+M))$。

#include<cstdio>
typedef long long ll;
const int N=55,M=505;
int n,cnt,m,ret,i,j,x,S,T;
int is[N],g[N],v[M],nxt[M],ed,d[N],q[N],h,t;
int id[N],vip[N],ban[N],f[N];
ll F[1<<17],G[1<<17],ans;
char a[N];
void add(int x,int y){d[y]++;v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void FWT(ll*a,int n){for(int d=1;d<n;d<<=1)for(int m=d<<1,i=0;i<n;i+=m)for(int j=0;j<d;j++){ll x=a[i+j],y=a[i+j+d];a[i+j]=x+y;}
}
void UFWT(ll*a,int n){for(int d=1;d<n;d<<=1)for(int m=d<<1,i=0;i<n;i+=m)for(int j=0;j<d;j++){ll x=a[i+j],y=a[i+j+d];a[i+j]=x-y;}
}
int main(){scanf("%d%s",&n,a);for(i=0;i<n;i++)if(a[i]=='?')is[i]=1;for(i=0;i<n;i++)for(scanf("%s",a),j=0;j<n;j++)if(a[j]=='Y')add(i,j);for(t=-1,i=0;i<n;i++)if(!d[i])q[++t]=i;while(h<=t)for(i=g[x=q[h++]];i;i=nxt[i])if(!(--d[v[i]]))q[++t]=v[i];for(i=0;i<n;i++)if(is[q[i]])id[m++]=q[i];cnt=m/2,ret=m-cnt+1;for(vip[1]=1,i=cnt;i<m;i++)vip[id[i]]=1;for(S=0;S<1<<cnt;S++){for(i=0;i<n;i++)ban[i]=f[i]=0;for(i=0;i<cnt;i++)if(S>>i&1)ban[id[i]]=1;for(i=0;i<n;i++){x=q[i];if(!x)f[x]=1;if(ban[x])f[x]=0;if(!f[x])continue;if(!vip[x])for(j=g[x];j;j=nxt[j])f[v[j]]^=1;}for(T=0,i=cnt;i<m;i++)if(f[id[i]])T|=1<<(i-cnt);if(f[1])T|=1<<(ret-1);F[T]++;}for(S=0;S<1<<(m-cnt);S++){for(i=0;i<n;i++)ban[i]=f[i]=0;for(i=0;i<(m-cnt);i++)if(S>>i&1)ban[id[i+cnt]]=1;for(i=n-1;~i;i--){x=q[i];if(x==1){f[x]=1;continue;}if(ban[x])continue;for(j=g[x];j;j=nxt[j])f[x]^=f[v[j]];}for(T=0,i=cnt;i<m;i++)if(f[id[i]])T|=1<<(i-cnt);if(f[1])T|=1<<(ret-1);G[T]++;}FWT(F,1<<ret),FWT(G,1<<ret);for(i=0;i<1<<ret;i++)F[i]*=G[i];UFWT(F,1<<ret);for(i=0;i<1<<ret;i++)if(__builtin_popcount(i)&1^1)ans+=F[i];return printf("%lld",ans),0;
}

  

转载于:https://www.cnblogs.com/clrs97/p/5768648.html

BZOJ3515 : EvenPaths相关推荐

最新文章

  1. linux看硬盘io,linux查看硬盘IO
  2. 首页被锁定7939的解决办法
  3. 提取HTML代码中文字的C#函数
  4. Uniform Grid Quadtree kd树 Bounding Volume Hierarchy R树 搜索
  5. Javascript 笔记与总结(2-11)暴力操作节点
  6. android listview 自动循环滚动条,ListView的自动循环滚动显示【原创】
  7. 信息论-Shannon entropy-Kullback-Leibler (KL) divergence-cross-entropy
  8. 【数据结构与算法】之深入解析“两数相除”的求解思路与算法示例
  9. javascript在html中的延迟与异步
  10. retryexec.java 94_解决feign调用接口不稳定的问题
  11. 计算机网络之物理层:5、数据的交换方式(电路交换、报文交换、分组交换)
  12. 【Elasticsearch】Elasticsearch:聚合 操作
  13. python中线程同步_Python线程同步在实际应用中功能体现
  14. ELK收集日志到mysql
  15. 补码加减法判断进位判断是否溢出的总结
  16. php mysql账号注册_php mysql用户注册登陆代码_PHP教程
  17. logit回归怎么看显著性_spss logistic回归分析结果如何分析
  18. python+selenium从excel读取成语到谷歌搜索得到搜索结论数
  19. 零基础学习 自动化编程- 第一天 计算机语言
  20. 4个让你相见恨晚的电脑操作技巧

热门文章

  1. np.percentile()函数超详解 异常值极端值百分位四分位数
  2. Tengine AIFramework框架
  3. 科技公司重新关注2级以上驾驶员辅助
  4. 激光雷达Lidar与毫米波雷达Radar:自动驾驶的利弊
  5. NVIDIA GPUs上深度学习推荐模型的优化
  6. 2021年大数据基础(一):大数据概念
  7. 2021年大数据常用语言Scala(五):基础语法学习 字符串
  8. 2021年大数据Spark(十四):Spark Core的RDD操作
  9. 【嵌入式】从STM32F103ZET6移植到STM32F103RCT6的流程
  10. 服务器创建和附加虚拟磁盘,Windows 7 虚拟硬盘中的新增功能