BZOJ2004: [Hnoi2010]Bus 公交线路
Posted QYP_2002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ2004: [Hnoi2010]Bus 公交线路相关的知识,希望对你有一定的参考价值。
2004: [Hnoi2010]Bus 公交线路
Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 747 Solved: 512
[Submit][Status][Discuss]
Description
Input
Output
仅包含一个整数,表示满足要求的方案数对30031取模的结果。
Sample Input
样例二:5 2 3
样例三:10 2 4
Sample Output
3
81
HINT
思路{
P,K小得不行,想到了状态压缩。n的范围如此之大,考虑矩阵快速幂!
先从简单的状态压缩开始。设$dp[i][j]$为强制选第i号停车,从第i号开始的后面p个的停车状态。转移。
发现一个问题(1->3,2->4)和(2->4,1->3)属于同一种情况,所以我们只需要考虑dp[i-1]->dp[i]。
关键就是后面状态j的转移关系了。发现dp[i-1][j‘]->dp[i][j]满足j‘变成j时实际位置对应的状态中的二进制数的位数+1
那么先删去i-1位置的数,j‘-=(1<<(p-1)),然后j‘<<1,变成对应的位置,由于j‘->j时只有一个相对位置发生了变化,那么j‘^=j,判断j‘的二进制数中1的个数是否为1即可。
那么转移方程就出来了。考虑构造矩阵。
暴力构造矩阵的话大小是(2^p)^2的显然不行,我们只需考虑后面的p位中有k位有车的状态,不妨先DFS找出所有的状态,然后两两枚举即可。注意转移关系在矩阵中对应的位置
不难发现构造的矩阵大小是(C(p-1,k-1))的,那这个就很对了。
所以总的复杂度是O(logn*C(p-1,k-1)^3+p!)的。
}
#include<bits/stdc++.h> #define ll long long #define RG register #define il inline #define N 200 #define mod 30031 using namespace std; int n,k,p,que[N]; struct matrix{ int n,m; ll ma[N][N]; void clear(){memset(ma,0,sizeof(ma));n=m=0;} matrix operator *(const matrix & a)const { matrix c;c.clear(); c.n=n,c.m=a.m; for(int i=1;i<=c.n;++i){ for(int j=1;j<=c.m;++j){ for(int k=1;k<=m;++k){ c.ma[i][j]+=ma[i][k]*a.ma[k][j]; } (c.ma[i][j]+=mod)%=mod; } } return c; } }; matrix qp(matrix a,ll b){ if(b==1)return a;if(b==2)return a*a; matrix tmp=qp(a,(b>>1)); tmp=tmp*tmp; if(b&1)tmp=tmp*a; return tmp; } void dfs(int pos,int num,int cnt){ if(cnt==k){que[++que[0]]=num;return;} for(int i=pos-1;i!=-1;i--) dfs(i,num+(1<<i),cnt+1); } #define lowbit(o) ( (o) & (-o) ) bool check(int x,int y){ int Temp=x-(1<<(p-1)); Temp<<=1;Temp^=y; if(Temp==lowbit(Temp))return 1; return 0; } int main(){ scanf("%d%d%d",&n,&k,&p); dfs(p-1,(1<<(p-1)),1); matrix temp;temp.clear();temp.n=temp.m=que[0]; matrix ans;ans.clear();ans.ma[1][1]=1;ans.n=que[0],ans.m=1; for(int i=1;i<=que[0];++i){ for(int j=1;j<=que[0];++j){ if(check(que[i],que[j]))temp.ma[j][i]=1; } } temp=qp(temp,n-k); ans=temp*ans; cout<<ans.ma[1][1]; return 0; }
以上是关于BZOJ2004: [Hnoi2010]Bus 公交线路的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ2004[Hnoi2010]Bus 公交线路 状压+矩阵乘法
BZOJ 2004: [Hnoi2010]Bus 公交线路 [DP 状压 矩阵乘法]