【XSY1285】【BZOJ3814】【清华集训2014】简单回路 状压DP
来源:互联网 发布:pc网络电视直播软件 编辑:程序博客网 时间:2024/05/16 11:30
题目描述
给你一个
题解
简单插头DP
先用DP求出前面
其实状态数很少的(不到
时间复杂度:
代码
#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<ctime>#include<utility>using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair<int,int> pii;ll p=1000000007;int c[100010];int d[1010];int ld[1010][10];int rd[1010][10];int cnt;int n,m,k,q;int la[10];int ra[10];int set(int s,int x,int v){ s&=~(3<<(2*(x-1))); s|=v<<(2*(x-1)); return s;}int get(int s,int x){ return (s>>(2*(x-1)))&3;}int st[10];void dfs(int x,int s){ if(x>m+1) { int i; int now=0; for(i=1;i<=m+1;i++) { if(get(s,i)==1) st[++now]=i; else if(get(s,i)==2) { la[i]=st[now]; ra[st[now]]=i; now--; } if(now<0) return; } if(now>0) return; for(i=1;i<=m+1;i++) fprintf(stderr,"%d",get(s,i)); fprintf(stderr,"\n"); d[++cnt]=s; c[s]=cnt; memcpy(ld[cnt],la,sizeof la); memcpy(rd[cnt],ra,sizeof ra); return; } int i; for(i=0;i<=2;i++) dfs(x+1,set(s,x,i));}void add(ll &x,ll y){ x=(x+y)%p;}struct dp{ int a[1010][10]; ll f[1010][10][200]; void solve() { f[1][1][1]=1; int i,j,k; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) for(k=1;k<=cnt;k++) { if(!f[i][j][k]) continue; int s=d[k]; int l=get(s,j); int r=get(s,j+1); if(a[i][j]) { if(!l&&!r) add(f[i][j+1][k],f[i][j][k]); continue; } if(!l) if(!r) { add(f[i][j+1][k],f[i][j][k]); int v=set(s,j,1); v=set(v,j+1,2); add(f[i][j+1][c[v]],f[i][j][k]); } else if(r==1) { add(f[i][j+1][k],f[i][j][k]); int v=set(s,j,1); v=set(v,j+1,0); add(f[i][j+1][c[v]],f[i][j][k]); } else { add(f[i][j+1][k],f[i][j][k]); int v=set(s,j,2); v=set(v,j+1,0); add(f[i][j+1][c[v]],f[i][j][k]); } else if(l==1) { if(!r) { add(f[i][j+1][k],f[i][j][k]); int v=set(s,j,0); v=set(v,j+1,1); add(f[i][j+1][c[v]],f[i][j][k]); } else if(r==1) { int v=set(s,j,0); v=set(v,j+1,0); v=set(v,rd[k][j+1],1); add(f[i][j+1][c[v]],f[i][j][k]); } else {// fprintf(stderr,"orzzjt\n"); } } else { if(!r) { add(f[i][j+1][k],f[i][j][k]); int v=set(s,j,0); v=set(v,j+1,2); add(f[i][j+1][c[v]],f[i][j][k]); } else if(r==1) { int v=set(s,j,0); v=set(v,j+1,0); add(f[i][j+1][c[v]],f[i][j][k]); } else { int v=set(s,j,0); v=set(v,j+1,0); v=set(v,ld[k][j],2); add(f[i][j+1][c[v]],f[i][j][k]); } } } for(j=1;j<=cnt;j++) if(!get(d[j],m+1)) add(f[i+1][1][c[d[j]<<2]],f[i][m+1][j]); } }};dp a,b;int tot;int e1[10];int e2[10];int op[1010];int f[1010];struct list{ int h[210]; int v[100010]; int t[100010]; int n; list() { n=0; memset(h,0,sizeof h);; } void add(int x,int y) { n++; v[n]=y; t[n]=h[x]; h[x]=n; }};list e;int find(int x){ return f[x]==x?x:f[x]=find(f[x]);}int check(int x,int y){ if(x==53&&y==53) int xxx=1; int i; for(i=1;i<=m+1;i++) { bool x1=get(d[x],i); bool y1=get(d[y],i); if(x1^y1) return 0; } for(i=1;i<=m+1;i++) f[i]=i; int fa; for(i=1;i<=m+1;i++) if(get(d[x],i)) { fa=find(i); if(get(d[x],i)==1) f[find(i)]=find(rd[x][i]); if(get(d[y],i)==1) f[find(i)]=find(rd[y][i]); } for(i=1;i<=m+1;i++) if(get(d[x],i)&&find(i)!=fa) return 0; return 1;}int main(){ freopen("d2t1.in","r",stdin); freopen("d2t1.out","w",stdout); scanf("%d%d%d",&n,&m,&k); int j,l; int i,x,y; for(i=1;i<=k;i++) { scanf("%d%d",&x,&y); a.a[x][y]=b.a[n-x+1][y]=1; } dfs(1,0); for(i=1;i<=cnt;i++) for(j=1;j<=cnt;j++) if(check(i,j)) e.add(i,j); a.solve(); b.solve(); scanf("%d",&q); for(i=1;i<=q;i++) { scanf("%d%d",&x,&y); ll ans=0; for(j=1;j<=cnt;j++) { int s=d[j]; if(get(s,m+1)) continue; if(!get(s,y)) continue; int bo=1; tot=0; for(l=1;l<=m;l++) if(get(s,l)) { if((a.a[x][l]||a.a[x+1][l])) { bo=0; break; } tot++; e1[tot]=l; e2[tot]=get(s,l); } if(!bo) continue; for(l=e.h[j];l;l=e.t[l]) ans=(ans+a.f[x+1][1][c[s<<2]]*b.f[n-x+1][1][c[d[e.v[l]]<<2]])%p; } printf("%lld\n",ans); } return 0;}
阅读全文
0 0
- 【XSY1285】【BZOJ3814】【清华集训2014】简单回路 状压DP
- bzoj3814 简单回路
- UOJ#37.【清华集训2014】主旋律 状压DP
- 【清华集训2014】mex
- 【清华集训2014】mex
- 【清华集训2014】mex
- 【清华集训2014】mex
- 【清华集训2014】mex
- 【清华集训2014】【BZOJ3817】Sum
- 【清华集训2014】【BZOJ3811】玛里苟斯
- 【清华集训2014】【BZOJ3812】主旋律
- #46. 【清华集训2014】玄学
- 【JZOJ5316】【清华集训模拟】merge(DP、括号序)
- JZOJ 3547【清华集训2014】mex
- uoj#46. 【清华集训2014】玄学
- JZOJsenior3541.【清华集训2014】破冰派对
- [BZOJ3585][清华集训2014]mex 主席树
- JZOJ 5483. 【清华集训2017模拟11.26】简单路径
- NCPC 2016 A Artwork(并查集)
- 挑选pick
- HDOJ2050
- Linux Shell编程入门
- eclispe中//TODO的用法
- 【XSY1285】【BZOJ3814】【清华集训2014】简单回路 状压DP
- Jzoj3899 逻辑的连通性
- Spring黑马笔记入门二
- HDU-5046 Airport(二分+DLX重复覆盖)
- 关押罪犯
- HDOJ2054
- 1088. Rational Arithmetic (20)
- 使用Postman作为客户端和Web API 2作为服务器进行基于令牌的认证
- 排序——桶排序