您的位置:首页 > 其它

【BZOJ 2004】: [Hnoi2010]Bus 公交线路

2017-10-31 21:38 253 查看

题目链接:

  TP

题解:

   所以说,超显眼的数据范围啊。

  很显然我们对于每个P的区间都是要有k个站被bus停留,然后考虑转移的话应该是把这k个站里的某个bus往前走,那么转移也很显然了,n的范围很大,所以直接上矩阵。

代码:

#define Troy

#include <bits/stdc++.h>

using namespace std;

inline int read(){
int s=0,k=1;char ch=getchar();
while(ch<'0'|ch>'9')    ch=='-'?k=-1:0,ch=getchar();
while(ch>47&ch<='9')    s=s*10+(ch^48),ch=getchar();
return s*k;
}

const int N=129,mod=30031;

int n,k,p,BGM,stk
,m;

struct Matrix{
int a

;
Matrix(){memset(a,0,sizeof(a));}
inline void evoid(){
for(int i=0;i^m;++i)
a[i][i]=1;
}
inline friend Matrix operator *(const Matrix &x,const Matrix &y){
Matrix c;
for(int i=0;i^m;++i)
for(int j=0;j^m;++j)
for(int k=0;k^m;++k)
c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
return c;
}
inline friend Matrix operator ^(Matrix x,int b){
Matrix ret;ret.evoid();
while(b){
if(b&1)ret=ret*x;
b>>=1;x=x*x;
}return ret;
}
};

inline bool move_to(int to,int from){
from^=1<<p-1;
from<<=1;
int deta=from^to;
return (deta&(-deta))==deta;
}

int main(){
n=read(),k=read(),p=read();
register int i,j;
for(i=(1<<p-1);i^(1<<p);++i){
int x=i;
for(j=0;x;x^=(x&(-x)),++j);
if(j==k){
if(i==(1<<p)-(1<<p-k))
BGM=m;
stk[m++]=i;
}
}
Matrix ans,t;
ans.a[BGM][0]=1;
for(i=0;i^m;++i)
for(j=0;j^m;++j){
t.a[i][j]=move_to(stk[j],stk[i]);
}
ans=(t^(n-k))*ans;
printf("%d\n",ans.a[BGM][0]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: