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

那么一条$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;
}

  

BZOJ3515 : EvenPaths的更多相关文章

  1. 近期概况&总结

    下午考完英语的学考就要放假啦,是衡中的假期啊QAQ 所以灰常的激动,一点也不想写题(我不会告诉你其实假期只有一个晚上.. 自从CTSC&APIO回来之后就一直在机房颓颓颓,跟着zcg学了很多新 ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. PHP实现执行定时任务的几种思路详解

    转:https://segmentfault.com/a/1190000002955509 PHP本身是没有定时功能的,PHP也不能多线程.PHP的定时任务功能必须通过和其他工具结合才能实现,例如Wo ...

  2. protobuf-net 对象二进制序列化与反序列号(转)

    概述: Protobuf是google开源的一个项目,用户数据序列化反序列化,google声称google的数据通信都是用该序列化方法.它比xml格式要少的多,甚至比二进制数据格式也小的多. Prot ...

  3. javascript中求浏览器窗口可视区域兼容性写法

    1.浏览器窗口可视区域大小 1.1 对于IE9+.Chrome.Firefox.Opera 以及 Safari:•  window.innerHeight - 浏览器窗口的内部高度•  window. ...

  4. hdu 2232 矩阵 ***

    一天四个不同的机器人a.b.c和d在一张跳舞毯上跳舞,这是一张特殊的跳舞毯,他由4个正方形毯子组成一个大的正方形毯子,一开始四个机器人分别站在4 块毯子上,舞蹈的每一步机器人可以往临近(两个毯子拥有同 ...

  5. hdu 4389 数位dp

    求区间内满足x%fx==0的数的个数,fx为该数各个位数上的数字之和Sample Input21 1011 20 Sample OutputCase 1: 10Case 2: 3 大小不是你想开,想开 ...

  6. 借助mosquitto“实时”远程监控服务器数据库运行状态

    公司的项目还处于开发阶段,我把整个后台服务临时放在阿里云上供前端测试,用的阿里云的ECS云服务器,HTTP请求服务器和数据库服务都安装在一台机子上(穷啊,凑合用),做测试用,配置相当低:单核1Gb.其 ...

  7. 基于socket、多线程的客户端服务器端聊天程序

    服务器端: using System; using System.Windows.Forms; using System.Net.Sockets; using System.Net;//IPAddre ...

  8. [荐]javascript Date format(js日期格式化)

    cnblog:http://www.cnblogs.com/zhangpengshou/archive/2012/07/19/2599053.html 方法一: // 对Date的扩展,将 Date  ...

  9. HTML5头部标签备忘

    DOCTYPE DOCTYPE(Document Type),该声明位于文档中最前面的位置,处于html 标签之前,此标签告知浏览器文档使用哪种HTML 或者XHTML 规范. 推荐使用HTML5 推 ...

  10. HTML Entity Sets - All

    http://www.htmlentities.com/html/entities/ The view below displays the characters used in the offici ...