题意有点儿绕?

容易发现,题意相当于在说,如果某一格有水,那么 ban 掉上一行后,让与其连同的所有格子被画上水。

所以我们从上到下枚举行,依次 ban 掉每一行,然后数连通块个数即可。

需要注意的是不连通的部分答案应该相乘,连通的部分答案应该相加。

但是这样做是 \(O(n^2m)\) 的,需要优化。

从上到下 ban 掉每一行的过程有点儿像删边,那么我们反过来加边。这样用并查集是很容易维护连通块个数的。

复杂度 \(O(nm\alpha(nm))\)。

加边时,如果合并了两个连通块,两列之间的方案是互不影响的,需要乘起来,在每一行合并结束后需要让每个连通块的方案数加 \(1\)。(全选)

人懒写了 \(O(nm\log nm)\) 就跑路了(

#include<cstdio>
const int M=1005,mod=1e9+7;
int n,m,cnt,id[M][M],f[M*M],siz[M*M],sum[M*M];char s[M][M];int ans(1);
inline int Find(const int&u){
return f[u]==u?u:f[u]=Find(f[u]);
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)scanf("%s",s[i]+1);
for(int i=2;i<n;++i)for(int j=2;j<m;++j)id[i][j]=++cnt,f[id[i][j]]=id[i][j],sum[id[i][j]]=1;
for(int i=n-1;i>1;--i){
for(int j=2;j<m;++j)if(s[i][j]=='.'&&s[i][j-1]=='.')f[Find(id[i][j])]=Find(id[i][j-1]);
for(int j=2;j<m;++j)if(s[i][j]=='.'&&s[i+1][j]=='.'&&Find(id[i][j])!=Find(id[i+1][j])){
const int x=Find(id[i][j]),y=Find(id[i+1][j]);
sum[x]=1ll*sum[x]*sum[y]%mod;f[y]=x;
}
for(int j=2;j<m;++j)if(s[i][j]=='.'&&Find(id[i][j])==id[i][j])++sum[id[i][j]];
}
for(int i=2;i<n;++i)for(int j=2;j<m;++j){
if(s[i][j]=='.'&&Find(id[i][j])==id[i][j])ans=1ll*ans*sum[id[i][j]]%mod;
}
printf("%d",ans);
}

最新文章

  1. HTML5移动Web开发(六)——定义一个内容策略
  2. poj 2524 (并查集)
  3. JS中先有Object还是先有Function?
  4. [转]ionic项目之上传下载数据
  5. android生成json
  6. Android IOS WebRTC 音视频开发总结(三十)-- ice协议异同
  7. Eclipse的LogCat总是自动清空怎么办?
  8. 学习VI的强文,新工作需要呀
  9. android关于图片缩放
  10. Javascript知识——事件
  11. HDU1969:Pie(二分)
  12. 如何自建appender扩展Log4j框架
  13. AtomicInteger类的理解及使用
  14. MVCC 能解决幻读吗?
  15. pyhton抛出自定义的异常
  16. Elasticsearch5.4署遇到的问题
  17. Linux 下SHELL脚本自动同步文件
  18. AngularJS控制器和AngularJS过滤器的学习(3)
  19. 使用ABP框架踩过的坑系列1
  20. 201621123037 《Java程序设计》第9周学习总结

热门文章

  1. JSP页面重定向与页面内容转发
  2. Centos下安装配置WordPress与nginx教程
  3. Loadrunner 11 中的Java Vuser
  4. UITextView模拟UITextField 设置Placeholder属性 --董鑫
  5. 一键部署lnmp
  6. notepad++颜色属性解释
  7. erange.heetian.com 回显任意账号
  8. Redis 源码简洁剖析 15 - AOF
  9. 『无为则无心』Python面向对象 — 52、私有成员方法(类中行为的封装)
  10. c++基础的记录(随笔记录一些基础的东西)