【题意】n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n。给定n,k,p,求满足要求的方案数%30031。n<=10^9,k<=p<=10

【算法】状压DP+矩阵快速幂

【题解】开始没看到p<=10,其实很显然p>k的话第一车就不满足要求了。考虑相邻停靠点没有关键信息,只能状压。

因为车都是从头开到尾的,所以直接考虑i~i-p+1的公车停靠状态就行了(i-p和i的距离为p,也就是必须跳到i,因此考虑i-p没有意义)。

设$f[i][S]$表示考虑第i个位置(最快的车可能到i),i~i-p+1的公车停靠状态为S的方案数,并且强制S的最低位为1(从前往后从低到高)。

$$f[i][S]=\sum f[i-1][S']$$

将S右移一位,然后枚举0~p中没有1的位置插入一个1得到的就是合法的S‘,然后把所有状态放在矩阵中就可以快速幂n-k次了。

注意到S是有效状态当且仅当S中含有恰好k个1,所以预处理合法状态数是C(p,k)的,这样复杂度就可以保证了。

总复杂度O(C(p,k)^3*log n)。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,MOD=;
int n,k,p,tot,c[N][N],q[N*],A[N][N],ANS[N][N];
void multply(int a[N][N],int b[N][N]){
for(int i=;i<=tot;i++){
for(int j=;j<=tot;j++){
c[i][j]=;
for(int k=;k<=tot;k++){
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%MOD;
}
}
}
for(int i=;i<=tot;i++)for(int j=;j<=tot;j++)b[i][j]=c[i][j];
}
int main(){
scanf("%d%d%d",&n,&k,&p);
for(int S=;S<(<<p);S++)if(S&){
int num=;
for(int i=;i<p;i++)if(S&(<<i))num++;
if(num!=k)continue;
tot++;q[S]=tot;
}
for(int S=;S<(<<p);S++)if(q[S]){
int s=S>>;
for(int i=;i<p;i++)if(!(s&(<<i))&&q[s|(<<i)])A[q[S]][q[s|(<<i)]]=;//
}
n-=k;
int s=(<<k)-;
ANS[q[s]][]=;
while(n){
if(n&)multply(A,ANS);
multply(A,A);
n>>=;
}
s=(<<k)-;
printf("%d",ANS[q[s]][]);
return ;
}

【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂的更多相关文章

  1. 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法

    题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...

  2. [Bzoj2004][Hnoi2010]Bus 公交线路(状压dp&&矩阵加速)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2004 看了很多大佬的博客才理解了这道题,菜到安详QAQ 在不考虑优化的情况下,先推$dp ...

  3. BZOJ 2004 公交线路(状压DP+矩阵快速幂)

    注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...

  4. BZOJ2004:[HNOI2010]Bus 公交线路(状压DP,矩阵乘法)

    Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定 ...

  5. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

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

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

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

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

  8. 『公交线路 状压dp 矩阵乘法加速』

    公交线路 Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的 ...

  9. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

随机推荐

  1. 最简单的Linux下apache+mysql+php安装

    转载:http://www.jb51.net/article/29843.htm ubuntu下需要先更新系统后 流程笔记: 1.打开终端,输入“sudo apt-get install apache ...

  2. JDK1.8最新特性--Lambda表达式(重点)

    一个旧版本JDK简单匿名类的用例如下所示: // Java 8之前: JButton show = new JButton("Show"); show.addActionListe ...

  3. POJ3709_K-Anonymous Sequence

     题意很简单,给你若干个数字,你需要减去一些数字,使得在数列中的每个数字出现的次数不少于k次. 一开始我们都会想到是用DP,于是很快我们就可以得出状态为搞定前面i个数所需要花费的最小代价用f[i]表示 ...

  4. 循环 与 next()

  5. Linux进入单用户模式(passwd root修改密码)

    进入单用户模式——passwd root修改密码 1.在grub 页面输入a,进入修改内核模式 2.在内核的结尾“/”,输入空格,在输入single,回车 3.启动系统,进入单用户模式 4.Passw ...

  6. UVA10859 Placing Lampposts

    我是题面 这道题使我知道了一种很神奇的方法,一定要认真看哦 如果没有被两盏灯同时照亮的边数应尽量大这个限制的话,这就是一道很经典的树形DP题--没有上司的舞会 很可惜,这个限制就在那里,它使得我辛苦写 ...

  7. P4169 [Violet]天使玩偶/SJY摆棋子

    题目背景 感谢@浮尘ii 提供的一组hack数据 题目描述 Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下.而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅 ...

  8. Oracle 同名字段的该行数据按照创建时间最新的隐藏其他

    1.需求,表  SYS_INFO   的 NAME 字段会重复,按照  创建时间CREATE_AT 字段,取最新一条,其他隐藏 SELECT * FROM (SELECT T.*,ROW_NUMBER ...

  9. 【BZOJ3712】Fiolki(并查集重构树)

    [BZOJ3712]Fiolki(并查集重构树) 题面 BZOJ 题解 很神仙的题目. 我们发现所有的合并关系构成了一棵树. 那么两种不同的东西如果产生反应,一定在两个联通块恰好联通的时候反应. 那么 ...

  10. Linux正确的关机方式

    本人还未入门,仅看书所得. Linux不建议的是直接关电源.Linux后台可能有多人在工作,直接关电源可能造成文件的毁坏. 正常关机之前应该干两件事:一.查看一下谁在线:二.通知一下别人啦,通知别人可 ...