Description

小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距
离均为1km。 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计线路:
1.设共K辆公交车,则1到K号站作为始发站,N-K+1到N号台作为终点站。
2.每个车站必须被一辆且仅一辆公交车经过(始发站和
终点站也算被经过)。 
3.公交车只能从编号较小的站台驶往编号较大的站台。 
4.一辆公交车经过的相邻两个
站台间距离不得超过Pkm。 在最终设计线路之前,小Z想知道有多少种满足要求的方案。由于答案可能很大,你只
需求出答案对30031取模的结果。

Input

仅一行包含三个正整数N K P,分别表示公交车站数,公交车数,相邻站台的距离限制。
N<=10^9,1<P<=10,K<N,1<K<=P

Output

仅包含一个整数,表示满足要求的方案数对30031取模的结果。

Sample Input

样例一:10 3 3
样例二:5 2 3
样例三:10 2 4

Sample Output

1
3
81

HINT

【样例说明】
样例一的可行方案如下: (1,4,7,10),(2,5,8),(3,6,9)
样例二的可行方案如下: (1,3,5),(2,4) (1,3,4),(2,5) (1,4),(2,3,5) 
P<=10 , K <=8
 
正解:状压$dp$+矩阵快速幂优化。
以前考过,当时什么都不会,现在看来还是不难吧。。
不过一直在想矩阵快速幂会$T$啊,结果就被告知状态数其实很少,可以把它离散化(差不多这意思吧)。。
所以大概就是设$f[i][j]$表示到了第$i$个站,所有公交车离这个车站的距离的状态为$j$,这个转移是暴力的。
乍一看,$j$可以取$[0,2^{p}-1]$这么多状态,但是我们可以发现,每次都有一个公交车与这个车站的距离为$0$,所以我们状态数可以$/2$。
然后我们又可以发现,$j$里面一定有$k-1$个$1$,那么我们算一下$\binom{p-1}{k-1}$,发现最大只有$\binom{9}{4}=126$。
于是我们把这些状态压到一个数组里,如果$i$状态可以转移到$j$状态,那么转移矩阵的$[i][j]$这个位置就可以赋为$1$。
那么初始状态是$f[k][2^{p}-2]=1$,乘上转移矩阵的$n-k$次方,找到$f[n][2^{p}-2]$就是答案了。
 #include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define rhl (30031) using namespace std; struct data{ int m[][]; }a,b; int st[],n,k,p,sz,now; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il int calc(RG int s){
RG int res=; while (s) res+=s&,s>>=; return res;
} il int can(RG int i,RG int j){
RG int x;
if (st[i]>>(p-)&){
x=(st[i]^(<<(p-)))<<;
return (x|)==st[j];
}
if ((st[i]<<)==st[j]) return ;
for (RG int s=;s<p;++s)
if (st[i]>>s&){
x=(st[i]^(<<s))<<;
if ((x|)==st[j]) return ;
}
return ;
} il data mul(data a,data b){
data c;
for (RG int i=;i<=sz;++i)
for (RG int j=;j<=sz;++j){
c.m[i][j]=;
for (RG int k=;k<=sz;++k)
(c.m[i][j]+=a.m[i][k]*b.m[k][j])%=rhl;
}
return c;
} il data qpow(data a,RG int b){
data ans=a; --b;
while (b){
if (b&) ans=mul(ans,a);
a=mul(a,a),b>>=;
}
return ans;
} int main(){
#ifndef ONLINE_JUDGE
freopen("bus.in","r",stdin);
freopen("bus.out","w",stdout);
#endif
cin>>n>>k>>p;
for (RG int s=;s<(<<p);++s)
if (!(s&) && calc(s)==k-) st[++sz]=s;
for (RG int i=;i<=sz;++i)
for (RG int j=;j<=sz;++j)
if (can(i,j)) b.m[i][j]=;
for (RG int i=;i<=sz;++i)
if (st[i]+==(<<k)-) a.m[][now=i]=;
b=qpow(b,n-k),a=mul(a,b);
cout<<a.m[][now]; return ;
}

bzoj2004 [Hnoi2010]公交线路的更多相关文章

  1. BZOJ2004 HNOI2010公交线路(状压dp+矩阵快速幂)

    由数据范围容易想到矩阵快速幂和状压. 显然若要满足一辆公交车的相邻站台差不超过p,则每相邻p个站台中每辆车至少经过一个站台.可以发现这既是必要的,也是充分的. 开始的时候所有车是相邻的.考虑每次把一辆 ...

  2. 【BZOJ2004】公交线路(动态规划,状态压缩,矩阵快速幂)

    [BZOJ2004]公交线路(动态规划,状态压缩,矩阵快速幂) 题面 BZOJ 题解 看到\(k,p\)这么小 不难想到状态压缩 看到\(n\)这么大,不难想到矩阵快速幂 那么,我们来考虑朴素的\(d ...

  3. [HNOI2010]公交线路

    题目 发现\(n\)比较大,但是\(k,p\)都很小,考虑矩乘使得复杂度倾斜一下 发现所有车的最大间隔都是\(p\),还保证\(k<p\),于是我们可以考虑压下最后\(p\)位的情况 于是设\( ...

  4. 洛谷 P3204 [HNOI2010]公交线路

    题面 luogu 题解 矩阵快速幂\(+dp\) 其实也不是很难 先考虑朴素状压\(dp\) \(f[i][S]\) 表示最慢的车走到了\(i\),\([i, p+i-1]\)的覆盖情况 状态第一位一 ...

  5. [HNOI2010] 公交线路 bus

    标签:状态压缩+矩阵快速幂. 题解: 首先看范围,p<=10,那么我们可以想到状态压缩.我们把从一个长度为10的区间进行压缩,1代表可以,那么当值一个区间的1的个数为k个,我们就认为他是合法的. ...

  6. 【BZOJ2004】[Hnoi2010]Bus 公交线路 状压+矩阵乘法

    [BZOJ2004][Hnoi2010]Bus 公交线路 Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1 ...

  7. 【BZOJ2004】[HNOI2010]Bus 公交线路

    [BZOJ2004][HNOI2010]Bus 公交线路 题面 bzoj 洛谷 题解 $N$特别大$P,K$特别小,一看就是矩阵快速幂+状压 设$f[S]$表示公交车状态为$S$的方案数 这是什么意思 ...

  8. AMap公交线路查询

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta http ...

  9. Android百度地图开发(五)公交线路详情搜索、多条线路显示

    一.公交线路详情检索 获取公交线路的详情主要分来两步,1.获取公交线路的Uid,2.通过Uid获取公交线路详情. 1.获取公交线路的Uid: /* * 获得公交线路图的Uid,并且根据系Uid发起公交 ...

随机推荐

  1. svn的branch truck tag

    对于branch truck tag一直迷迷糊糊的,想搞明白,但是一直又没来弄明白,最近就用了这种方式来开发 可以我又不是完全了解怎么操作,所以查看了下资料,这个解释得很详细呀,连我都看得懂的东西,真 ...

  2. oracle 操作实例(一)----rman 全备恢复

    一,环境背景 拥有全备数据库 全备脚本: export TMP=/tmp export TMPDIR=$TMP export ORACLE_BASE=/u01 export ORACLE_SID=pr ...

  3. nodejs基础知识查缺补漏

    1. 单线程.异步I/O.对比php nodejs是单线程的,但是是异步I/O,对于高并发时,它也能够快速的处理请求,100万个请求也可以承担,但是缺点是非常的耗内存,但是我们可以加大内存, 所以能用 ...

  4. 关于GitHub在VS中出现“已经存在master版本,无法……”的错误解决方案

    引用:http://www.cnblogs.com/SmallZL/p/3637613.html(这篇已经很详细说明如何使用Vs+GitHub),我这里做补充: VS2013已经集成了Git一部分控件 ...

  5. OpenGL进阶之Instancing

    Instancing Instancing绘制我想很多童鞋都不陌生,这个技术主要用来快速渲染大量相同的几何体,可以大大提高绘制效率.每个instance在shader中都有一个独一无二的索引,可以用来 ...

  6. elasticSearch2.4与grafana,stagemonitor集成做监控需要执行的mapping

    PUT /_template/stagemonitor-metrics-{ "template": "stagemonitor-metrics-*", &quo ...

  7. [转]win7 如何升级PowerShell

    本文转自:http://www.cnblogs.com/wenBlog/p/6198354.html 背景: 开发的PowerShell 脚本需要使用Invoke-RestMethod命令,发现在老的 ...

  8. 关闭Windows 系统当前连接的Wifi以及判断物理\虚拟网卡,有线\无线网卡

    1.关闭wifi ,调用Api [DllImport("Wlanapi.dll", SetLastError = true)] public static extern uint ...

  9. js之闭包

    函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个对Array的求和.通常情况下,求和的函数是这样定义的: function sum(arr) { ret ...

  10. Csharp: FreeTextbox 编辑器控件运行时错误: 'FTB_ResizeGalleryArea' 未定义

    ftb.imagegallery.aspx 改一下代码: <form id="Form1" runat="server" enctype="mu ...