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. element-ui日期组件DatePicker设置日期选择范围Picker Options

    element-UI提供了DatePicker日期选择器组件,可以让我们很方便的获取到日期,默认的选择是全部的日期都可以选择的,但是很多场景中我们要对日期选择范围做限定,比如出行日期就不能选过去的日期 ...

  2. JQuery实现表格的全选和反选,以及分页勾选保存(laypage插件分页的使用)

    需求: 1.全选与取消全选 2.单个勾选,点击表格单元格中checkbox勾选,也可以在点击行勾选,便与用户操作 3.分页勾选保存 4.固定表头 功能一: 说明:操作全选按钮的同时,遍历每一个tr中的 ...

  3. oracle中的exists理解

    select * from EB where exists (select * from BB where Code=EB.Code) 把select 外层表EB看成是循环的,把每一个值eb.code ...

  4. Ant利用第三方的task

    转自 http://blog.sina.com.cn/s/blog_3d21e545010006s9.html 一.如何使用第三方任务   Ant可以使用第三方任务,在使用第三方任务之前,需告知Ant ...

  5. Linux分区扩容

    lz在MAC上面使用Linux虚拟机,开始只建了一个分区,挂载在”/”目录下.现在硬盘空间不够了,所以lz就来给这个分区扩容. 首先,当然是要给虚拟机分配更多的硬盘空间喽(lz用的是VMware Fu ...

  6. 腾讯蔡晨:十年沉淀,腾讯iOA为企业安全保驾护航

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 背景:5月23-24日,以"焕启"为主题的腾讯"云+未来"峰会再广州召开,广东省各级政府机构领导.海 ...

  7. web前端与后台数据访问的对象封装

    前言:通常情况下,在不使用angularJS/nodeJS/react等这类完整性的解决方案的js时,前端与后台的异步交互都是使用Ajax技术进行解决 一:作为java web开发工程师可能以下代码是 ...

  8. Python之装饰器、迭代器和生成器

    在学习python的时候,三大“名器”对没有其他语言编程经验的人来说,应该算是一个小难点,本次博客就博主自己对装饰器.迭代器和生成器理解进行解释. 为什么要使用装饰器 什么是装饰器?“装饰”从字面意思 ...

  9. Java网络编程二--基于UDP的编程

    DatagramSocket对象为基于UDP协议的Socket 构造器提供可以选择性绑定到指定端口和ip 创建完对象后调用:receive(DatagramPacket p) send(Dategra ...

  10. html元素固定

    1.position 值 描述 static        默认.位置设置为 static 的元素,它始终会处于页面流给予的位置(static 元素会忽略任何 top.bottom.left 或 ri ...