zoukankan      html  css  js  c++  java
  • 【BZOJ2004】[Hnoi2010]Bus 公交线路 状压+矩阵乘法

    【BZOJ2004】[Hnoi2010]Bus 公交线路

    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

    题解:看到P和K很小想到状压。用f[i][S]表示已经覆盖了前i个车站,每个车的位置的状态为S的方案数(S只包含前P个车站)。

    由于n很大,考虑矩乘优化。我们将没有用的状态扔掉,最终矩阵大小是不超过$C_{10}^5 imes C_{10}^5=252 imes 252$的。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int P=30031;
    int n,m,k,tot;
    struct M
    {
    	int v[260][260];
    	M () {memset(v,0,sizeof(v));}
    	int * operator [] (int a) {return v[a];}
    	M operator * (const M &a) const
    	{
    		M b;
    		int i,j,k;
    		for(i=1;i<=tot;i++)	for(j=1;j<=tot;j++)	for(k=1;k<=tot;k++)	b.v[i][j]=(b.v[i][j]+v[i][k]*a.v[k][j])%P;
    		return b;
    	}
    }S,T;
    int r[1<<10],cnt[1<<10];
    inline void pm(int y)
    {
    	while(y)
    	{
    		if(y&1)	S=S*T;
    		T=T*T,y>>=1;
    	}
    }
    int main()
    {
    	scanf("%d%d%d",&n,&k,&m);
    	int i,j;
    	for(i=1;i<(1<<m);i++)
    	{
    		cnt[i]=cnt[i-(i&-i)]+1;
    		if(cnt[i]==k)	r[i]=++tot;
    	}
    	for(i=1;i<(1<<m);i++)	if(r[i])
    	{
    		if(i&1)	T[r[i]][r[(i>>1)|(1<<(m-1))]]++;
    		else	for(j=0;j<m;j++)	if((i>>j)&1)	T[r[i]][r[((i^(1<<j))>>1)|(1<<(m-1))]]++;
    	}
    	S[1][r[((1<<k)-1)<<(m-k)]]=1;
    	pm(n-k);
    	printf("%d",S[1][r[((1<<k)-1)<<(m-k)]]);
    	return 0;
    }
  • 相关阅读:
    关键字,保留字
    20181024
    php连接mysql数据并查询
    java 字符串的json格式数据转换成Map集合
    IntelliJ IDEA的一些快捷键
    Java的反射机制简述
    java主函数知识
    单例设计模式---懒汉式的多线程安全隐患
    java的单例设计模式(对象的延时加载)考试专用
    java的单例设计模式
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7965446.html
Copyright © 2011-2022 走看看