插头DP+矩阵乘法

  m喜闻乐见地达到了10^9级别。。而n<=7,并且没有障碍。。所以列与列之间的转移时一样的。。就可以上矩乘了。

  感觉自己快没救了。。看半天题解还是不懂。。

  http://www.cnblogs.com/staginner/archive/2012/09/14/2684712.html 题解其实讲的很清楚了。。

  在枚举转移的状态的时候想乱了好几次。。2^n枚举的是有没有右插头,处理新出现路径的姿势也和平时不同。。。

  剩下的就是矩乘了。。

 #include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
using namespace std;
const int maxzt=,modd=;
struct zs1{
int last[],tot;
inline int get(int x){
if(last[x])return last[x];
last[x]=++tot,zt[tot]=x;
return tot;
}
int zt[];
}hm;
int mp[];
int a[][],c[][],b[][],map[][][];
int len[];
int i,j,k,n,m,l; inline void decode(int x){
for(int i=n;i>=;i--)mp[i]=x&,x>>=;
}
bool u[];int id[];
inline int encode(){
int i,x=,cnt=;
memset(u,,);
for(i=;i<=n;mp[i]=id[mp[i]],x=x<<|mp[i],i++)
if(!u[mp[i]]&&mp[i]>)u[mp[i]]=,id[mp[i]]=++cnt;
return x;
} inline bool check(int prezt,int nowzt){
int i,up=,left,pre=,sm=n-;bool r;
decode(prezt);
// for(i=1;i<=n;i++)printf(" %d",mp[i]);printf(" %d\n",prezt);
for(i=;i<=n;i++){
r=(nowzt&(<<(i-)))>,left=mp[i];
// printf(" up:%d r:%d l:%d\n",up,r,left);
if((up&&r&&left)||(!up&&!r&&!left))return ;
if(!up){
if(left&&r)continue;
pre=i;
if(!r)up=mp[i];
if(!left)up=-;
}else{
if(left){
if(left==up&&(i<n||nowzt!=))return ;
if(up>){
mp[pre]=mp[i]=;
for(int j=;j<=n;j++)if(mp[j]==left)mp[j]=up;
}else mp[pre]=mp[i],mp[i]=;
}
if(r){
if(up>)mp[i]=up,mp[pre]=;
else mp[i]=mp[pre]=++sm;
}
if(left||r)up=;
}
}
return up==;
}
inline void prerun(){
int i,j,k;
hm.tot=;memset(hm.last,,sizeof(hm.last));
memset(mp,,sizeof(mp));
hm.get(),
mp[]=mp[n]=,hm.get(encode());//printf(" %d\n",encode());
for(i=;i<=hm.tot;i++){//printf(" %d\n",n) ;
int zt=hm.zt[i];decode(zt);
// for(j=1;j<=n;j++)printf(" %d",mp[j]);puts("");
for(j=;j<(<<n);j++)if(check(zt,j))
k=hm.get(encode()),
map[n][i][k]=;//,printf(" %d %d\n",j,k);
}
len[n]=hm.tot;
}
inline void multoa(){
int i;register int j,k;ll tmp;
for(i=;i<=l;i++)for(j=;j<=l;b[i][j]=tmp%modd,j++)
for(tmp=,k=;k<=l;k++)tmp+=(ll)a[i][k]*a[k][j];
for(i=;i<=l;i++)for(j=;j<=l;j++)a[i][j]=b[i][j];
}
inline void multoc(){
int i;register int j,k;ll tmp;
for(i=;i<=l;i++)for(j=;j<=l;b[i][j]=tmp%modd,j++)
for(tmp=,k=;k<=l;k++)tmp+=(ll)a[i][k]*c[k][j];
for(i=;i<=l;i++)for(j=;j<=l;j++)c[i][j]=b[i][j];
}
int main(){
for(i=;i<=;i++)n=i,prerun();//return 233;
while(scanf("%d",&n)!=EOF){
scanf("%d",&m);
if(n==&&m==){
puts("");continue;
}
if((n&)&&!(m&)){
puts("Impossible");continue;
}
memcpy(a,map[n],sizeof(map[n]));l=len[n];
memset(c,,sizeof(c));
for(i=;i<=l;i++)c[i][i]=;
while(m){
if(m&)multoc();
m>>=;if(m)multoa();
}
if(!c[][])puts("Impossible");else printf("%d\n",c[][]);//return 233;
}
return ;
}

发现我的矩乘比标程的慢了不少。。QAQ

本来要跑150ms的。。然后顺手加了对极限数据、无解的特判。。然后直接0ms吓哭...数据竟然这么水= =

[ZOJ3256] Tour in the Castle的更多相关文章

  1. ZOJ 3256 Tour in the Castle 插头DP 矩阵乘法

    题解 这题是一道非常好的插头题,与一般的按格转移的题目不同,由于m很大,要矩阵乘法,这题需要你做一个按列转移的插头DP. 按列转移多少与按格转移不同,但大体上还是基于连通性进行转移.每一列只有右插头是 ...

  2. 插头DP专题

    建议入门的人先看cd琦的<基于连通性状态压缩的动态规划问题>.事半功倍. 插头DP其实是比较久以前听说的一个东西,当初是水了几道水题,最近打算温习一下,顺便看下能否入门之类. 插头DP建议 ...

  3. DP:0

    小故事: A * "1+1+1+1+1+1+1+1 =?" * A : "上面等式的值是多少" B : *计算* "8!" A *在上面等式 ...

  4. Castle Core 4.0.0 alpha001发布

    时隔一年多以后Castle 项目又开始活跃,最近刚发布了Castle Core 4.0.0 的alpha版本, https://github.com/castleproject/Core/releas ...

  5. 对Castle Windsor的Resolve方法的解析时new对象的探讨

    依赖注入框架Castle Windsor从容器里解析一个实例时(也就是调用Resolve方法),是通过调用待解析对象的构造函数new一个对象并返回,那么问题是:它是调用哪个构造函数呢? 无参的构造函数 ...

  6. AOP之Castle DynamicProxy 动态代理

    这里主要介绍使用castle这个动态代理,在.net一些开源的框架里可以找到它的影子,就连微软的rchard也是使用这个进行方法拦截等可以基于这个进行方法拦截,在这个方面PostSharp算是比较好用 ...

  7. ASP.NET Core 整合Autofac和Castle实现自动AOP拦截

    前言: 除了ASP.NETCore自带的IOC容器外,我们还可以使用其他成熟的DI框架,如Autofac,StructureMap等(笔者只用过Unity,Ninject和Castle). 1.ASP ...

  8. POJ 1637 Sightseeing tour

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9276   Accepted: 3924 ...

  9. Euler Tour Tree与dynamic connectivity

    Euler Tour Tree最大的优点就是可以方便的维护子树信息,这点LCT是做不到的.为什么要维护子树信息呢..?我们可以用来做fully dynamic connectivity(online) ...

随机推荐

  1. 每周.NET前沿技术文章摘要(2017-05-17)

    汇总国外.NET社区相关文章,覆盖.NET ,ASP.NET等内容: .NET .NET Framework 4.7正式发布 链接: http://www.infoq.com/cn/news/2017 ...

  2. 栈和队列数据结构的相互实现[LeetCode]

    栈是先进后出,队列是先进后出,这里讨论一下两种数据结构之间的相互实现. 一.用两个栈实现队列 我们用一个栈来实现队列的进队操作(栈A),用另一个栈来实现队列的出队操作(栈B). 1.入队列: 把元素放 ...

  3. 【WebGL】《WebGL编程指南》读书笔记——第5章

    一.前言        终于到了第五章了,貌似开始越来越复杂了. 二.正文         Example1:使用一个缓冲区去赋值多个顶点数据(包含坐标及点大小) function initVerte ...

  4. HTML5 矩阵变换

    transforms 使用图形上下文对象的transforms方法修改变换矩阵,该方法的定义如下: context.transform(m11,m12,m21,m22,dx,dy); 其中m11,m1 ...

  5. Linux - Shell常用指令

    一.文件.目录操作命令 1.ls命令:显示文件和目录的信息 ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示文件属性,包括大小,日期,符号连接,是否可读写及 ...

  6. glimmer 3.02安装小记

    wget http://www.cbcb.umd.edu/software/glimmer/glimmer302.tar.gz tar xzfglimmer302.tar.gz cd glimmer3 ...

  7. Fiddler如何模拟弱网环境进行测试

    1.模拟弱网环境 打开Fiddler,Rules->Performance->勾选 Simulate Modem Speeds,勾选之后访问网站会发现网络慢了很多 2.Fiddler弱网的 ...

  8. jQuery Ajax 操作函数 (七)

    函数 描述 jQuery.ajax() 执行异步 HTTP (Ajax) 请求. .ajaxComplete() 当 Ajax 请求完成时注册要调用的处理程序.这是一个 Ajax 事件. .ajaxE ...

  9. TPYBoard v102 驱动28BYJ-48步进电机

    TPYBoard v102 驱动28BYJ-48步进电机 实验目的 了解步进电机的工作原理 学习步进电机的驱动方法 实验器材 TPYBoard v102 1块 微型步进电机(28BYJ-48) 1个 ...

  10. VC++平台上的内存对齐操作

    我们知道当内存的边界正好对齐在相应机器字长边界上时,CPU的执行效率最高,为了保证效率,在VC++平台上内存对齐都是默认打开的,在32位机器上内存对齐的边界为4字节:比如看如下的代码: struct ...