若$\min(n,m)<\min(n+1,m-1)$,则考虑计算左边与右边不连通的概率,然后用$1$减去它得到答案。

若$\min(n,m)\geq \min(n+1,m-1)$,则考虑计算对偶图中上边与下边不连通的概率。

同时当$n<m$时还可以旋转$90$°来交换$n$和$m$,使得$m\leq 9$。

那么问题转化为,给定$n\times m$的网格图,每个点颜色为$0,1,2$,每条边有存在的概率,求每个连通块不同时含有颜色$1$和$2$的概率。

连通性状压DP,设$f[i][j][S]$表示考虑到了$(i,j)$,轮廓线状态为$S$的概率。

其中$S$记录轮廓线上$m$个点所属连通块的最小表示,以及每个连通块的颜色。

为了避免map的使用,可以考虑扩展出所有状态后再进行排序,将相同状态的DP值合并,减小常数。

同时可以将$1$和$2$内部的边存在的概率设置为$1$,减小连通块的数量已达到优化状态数的效果。

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. typedef long long ll;
  5. const int N=115,M=1000000,P=1000000007;
  6. int n,m,o,i,j,k,_id[N][N],_wr[N][N],_wd[N][N],id[N][N],wr[N][N],wd[N][N];
  7. struct E{
  8. ll x;int y,v;
  9. E(){}
  10. E(ll _x,int _y,int _v){x=_x,y=_y,v=_v;}
  11. }e[2][M];
  12. int cnt[2];
  13. inline bool cmp(const E&a,const E&b){
  14. if(a.x!=b.x)return a.x<b.x;
  15. return a.y<b.y;
  16. }
  17. inline void up(int&a,int b){a=a+b<P?a+b:a+b-P;}
  18. inline int po(int a,int b){int t=1;for(;b;b>>=1,a=1LL*a*a%P)if(b&1)t=1LL*t*a%P;return t;}
  19. inline int read(){
  20. int x;
  21. scanf("%d",&x);
  22. return 1LL*x*po(100,P-2)%P;
  23. }
  24. inline int read2(){
  25. int x=read();
  26. x=(P+1-x)%P;
  27. return x;
  28. }
  29. inline void fix(){
  30. int m=cnt[o],t=0,i,j,k;
  31. sort(e[o],e[o]+m,cmp);
  32. for(i=0;i<m;i=j){
  33. for(k=0,j=i;j<m&&e[o][i].x==e[o][j].x&&e[o][i].y==e[o][j].y;j++)up(k,e[o][j].v);
  34. if(k)e[o^1][t++]=E(e[o][i].x,e[o][i].y,k);
  35. }
  36. cnt[o^=1]=t;
  37. }
  38. inline ll get(ll x,int y){return x>>(y<<2)&15;}
  39. inline void cal(ll&A,int&B){
  40. static int v[N],f[N];
  41. int i,x,t=0,C=0;
  42. for(i=0;i<=m;i++)v[i]=-1;
  43. for(t=i=0;i<m;i++){
  44. x=get(A,i);
  45. if(v[x]==-1){
  46. C|=(B>>(x<<1)&3)<<(t<<1);
  47. v[x]=t++;
  48. }
  49. f[i]=v[x];
  50. }
  51. for(A=0,B=C,i=m-1;~i;i--)A=A<<4|f[i];
  52. }
  53. inline void up0(ll A,int B,int C,int x,int y){
  54. A^=(get(A,x)^m)<<(x<<2);
  55. B|=y<<(m<<1);
  56. cal(A,B);
  57. e[o^1][cnt[o^1]++]=E(A,B,C);
  58. }
  59. inline void upl(ll A,int B,int C,int x,int y){
  60. int t=get(A,x-1);
  61. if(y+(B>>(t<<1)&3)==3)return;
  62. A^=(get(A,x)^t)<<(x<<2);
  63. B|=y<<(t<<1);
  64. cal(A,B);
  65. e[o^1][cnt[o^1]++]=E(A,B,C);
  66. }
  67. inline void upu(ll A,int B,int C,int x,int y){
  68. int t=get(A,x);
  69. if(y+(B>>(t<<1)&3)==3)return;
  70. B|=y<<(t<<1);
  71. e[o^1][cnt[o^1]++]=E(A,B,C);
  72. }
  73. inline void upul(ll A,int B,int C,int x,int y){
  74. int t=get(A,x),z=get(A,x-1);
  75. if(y+(B>>(t<<1)&3)==3)return;
  76. B|=y<<(t<<1);
  77. if((B>>(z<<1)&3)+(B>>(t<<1)&3)==3)return;
  78. B|=(B>>(z<<1)&3)<<(t<<1);
  79. ll S=z^t;
  80. for(int i=0;i<m;i++)if(get(A,i)==z)A^=S<<(i<<2);
  81. cal(A,B);
  82. e[o^1][cnt[o^1]++]=E(A,B,C);
  83. }
  84. int solve(){
  85. if(n<m){
  86. for(i=1;i<=n;i++)for(j=1;j<m;j++)wd[j][i]=_wr[i][j];
  87. for(i=1;i<n;i++)for(j=1;j<=m;j++)wr[j][i]=_wd[i][j];
  88. for(i=1;i<=n;i++)for(j=1;j<=m;j++)id[j][i]=_id[i][j];
  89. swap(n,m);
  90. }else{
  91. for(i=1;i<=n;i++)for(j=1;j<=m;j++)wd[i][j]=_wd[i][j],wr[i][j]=_wr[i][j],id[i][j]=_id[i][j];
  92. }
  93. cnt[o=0]=1;
  94. e[0][0]=E(0,0,1);
  95. for(i=m-1;~i;i--)e[0][0].x=e[0][0].x<<4|i;
  96. for(i=1;i<=n;i++)for(j=1;j<=m;j++){
  97. int pl=j>1?wr[i][j-1]:0,npl=(P+1-pl)%P,
  98. pu=i>1?wd[i-1][j]:0,npu=(P+1-pu)%P,
  99. pul=1LL*pl*pu%P,p0=1LL*npl*npu%P,t=id[i][j];
  100. pl=1LL*pl*npu%P;
  101. pu=1LL*pu*npl%P;
  102. cnt[o^1]=0;
  103. for(k=0;k<cnt[o];k++){
  104. if(pl)upl(e[o][k].x,e[o][k].y,1LL*e[o][k].v*pl%P,j-1,t);
  105. if(pu)upu(e[o][k].x,e[o][k].y,1LL*e[o][k].v*pu%P,j-1,t);
  106. if(pul)upul(e[o][k].x,e[o][k].y,1LL*e[o][k].v*pul%P,j-1,t);
  107. if(p0)up0(e[o][k].x,e[o][k].y,1LL*e[o][k].v*p0%P,j-1,t);
  108. }
  109. o^=1;
  110. fix();
  111. }
  112. int ret=0;
  113. for(i=0;i<cnt[o];i++)up(ret,e[o][i].v);
  114. return ret;
  115. }
  116. int main(){
  117. int r,c,flag=0;
  118. scanf("%d%d",&r,&c);
  119. if(c<=1)return puts("1"),0;
  120. if(min(r,c)<min(r+1,c-1)){
  121. flag=1;
  122. for(i=1;i<=r;i++)for(j=1;j<c;j++)_wr[i][j]=read();
  123. for(i=1;i<r;i++)for(j=2;j<c;j++)_wd[i][j]=read();
  124. for(i=1;i<r;i++)_wd[i][1]=_wd[i][c]=1;
  125. for(i=1;i<=r;i++)_id[i][1]=1,_id[i][c]=2;
  126. n=r,m=c;
  127. }else{
  128. for(i=1;i<=r;i++)for(j=1;j<c;j++)_wd[i][j]=read2();
  129. for(i=1;i<r;i++)for(j=2;j<c;j++)_wr[i+1][j-1]=read2();
  130. for(i=1;i<c-1;i++)_wr[1][i]=_wr[r+1][i]=1;
  131. for(i=1;i<c;i++)_id[1][i]=1,_id[r+1][i]=2;
  132. n=r+1,m=c-1;
  133. }
  134. int ans=solve();
  135. if(flag)ans=(P+1-ans)%P;
  136. return printf("%d",ans),0;
  137. }

  

BZOJ5207 : [Jsoi2017]隧道的更多相关文章

  1. SSH隧道应用, 突破网络限制

    文/怡文圣美 这篇文章可以帮你解决下面三个问题: 不能直连服务器, 要先登陆跳板机, 造成客户端工具无法连接服务器. 服务器没有公网IP, 且只允许公司IP访问, 要在家里操作要先远程桌面到工作机再登 ...

  2. 前端学HTTP之网关、隧道和中继

    前面的话 Web是一种强大的内容发布工具.人们已经从只在网上发送静态的在线文档,发展到共享更复杂的资源,比如数据库内容或动态生成的HTML页面.Web浏览器为用户提供了一种统一的方式来访问因特网上的内 ...

  3. ngrok反向隧道--获取内网IP

    ngrok反向隧道 前情提要:小明与小白各有一台主机,两台主机在同一内网,小明想直接通过内网ssh到小白的主机上.但是小白的ip地址会不断的变化,而小明不想每次都要麻烦小白查看ip.于是小明催生了一个 ...

  4. SSH正反向隧道

    正向隧道 拓扑如下: 说明: CLIENT不能直接访问WEB服务器,AGENT可访问WEB服务器: 在AGENT上通过创建ssh正向隧道,使CLIENT可以通过AGENT间接访问WEB服务器: AGE ...

  5. Windows下使用Xshell建立反向隧道

    反向隧道是一个进行内网穿透的简单而有用的方法.在Linux下通过OpenSSH和AutoSSH可以很容易地建立稳定的反向隧道.但是在Windows下,还能看到有人特意装个Cygwin来运行这些工具…… ...

  6. WPF的路由事件、冒泡事件、隧道事件(预览事件)

    本文摘要: 1:什么是路由事件: 2:中断事件路由: 3:自定义路由事件: 4:为什么需要自定义路由事件: 5:什么是冒泡事件和预览事件(隧道事件): 1:什么是路由事件 WPF中的事件为路由事件,所 ...

  7. XSHELL使用隧道

    线上系统中,搭建了一个elasticsearch环境,想要访问页面,发现环境的内网中没有windows机器,无法使用浏览器来直接进行web页面的访问,于是直接使用了XSELL中强大的功能"隧 ...

  8. HTTP权威协议笔记-7.集成点:网关、隧道及中继

    .8.1 网关 定义:网关类似与翻译器,它抽象出了一种能够到达资源的方法. 实用:网关可以自动将HTTP流量转换为其他协议,这样使用HTTP协议的一方就不需要了解其他协议,也可实现与其他程序或设备交互 ...

  9. Android终端配置isatap隧道使用IPV6的方法

    使用isatap隧道可以在手机有IPV4网络的情况下访问IPv6网络资源.关于isatap隧道的配置方法,清华.上交两所学校都给出了相应的在windows xp/2003,windows 2000,以 ...

随机推荐

  1. 阿里云人脸识别测试接口出错 返回Body:{ "errno": 3002, "err_msg": "ILLEGAL_PARAMETERS", "request_id": "672cba83-cf93-4ef4-9ce5-d87e51601632" }

    错误信息如下 返回Body:{ "errno": 3002, "err_msg": "ILLEGAL_PARAMETERS", ...... ...

  2. 将眼底图片生成的txt文件进行格式化处理

    # -*- coding: utf-8 -*- """ 将图片转换生成的txt文件进行格式化处理 """ import os import ...

  3. Redis cluster集群模式的原理

    redis cluster redis cluster是Redis的分布式解决方案,在3.0版本推出后有效地解决了redis分布式方面的需求 自动将数据进行分片,每个master上放一部分数据 提供内 ...

  4. pandas处理finance.yahoo股票数据 WTI CL USO OIL

    1.参考 用Python做科学计算-基础篇 »matplotlib-绘制精美的图表 »快速绘图 使用pyplot模块绘图 2.数据来源 CL USO OIL 3.代码 #encoding='utf-8 ...

  5. Python_copy_深浅拷贝

    对于数字和字符串来说,无论是‘’赋值‘’还是‘’深拷贝‘’还是‘’浅拷贝‘’都是指向的同一个地址 深浅拷贝是copy类下的方法,创建方式为 import copy copy.copy() #浅拷贝 c ...

  6. BZOJ3172 [Tjoi2013]单词 字符串 SA ST表

    原文链接http://www.cnblogs.com/zhouzhendong/p/9026543.html 题目传送门 - BZOJ3172 题意 输入$n(n\leq 200)$个字符串,保证长度 ...

  7. js去掉前后空格

    //去前后空格 data=data.replace(/(^\s*)|(\s*$)/g, "");

  8. 046 Oracle执行慢的SQL

    -- 执行最慢的sql SELECT * FROM (SELECT sa.SQL_TEXT, sa.SQL_FULLTEXT, sa.EXECUTIONS as "exeCount" ...

  9. 028 IDEA中下载与上传程序

    在学习的时候,更多的时候在使用eclipse,但是在使用过程中,IDEA有时候使用起来更加方便轻松. 关于,在使用过程中的一些常识,这里谢谢写写文档. 一:拉代码 1.说明 在第一次开始项目的时候,需 ...

  10. Python上下文管理器 with

    对于系统资源的操作,如:文件操作.数据库操作等,我们往往打开文件.连接数据库后忘了将其close掉,这时就可能会引发异常,因此我们常用的做法是: # coding:utf-8 f = open(&qu ...