题解:P2151
wallace_QwQ · · 题解
前言:
辅导机构练习比赛把这道题的
蒟蒻惨遭薄纱,于是就有了这么一篇加强版的题解。
注:以下所有下标均经过加1处理。
考虑到加强版后的
我们设
这样会有
显然不好用矩阵快速幂直接维护。
那么,我们不妨再令
经过推导我们得到:
-
A_{i,t}=A_{k,t-1}\sum_kg_{k,i}-B_{i,t-1} -
B_{i,t}=A_{i,t-1}\sum_k(g_{i,k}-1)
那么答案即为
然后就可以愉快地矩阵加速了。
什么?
你问这玩意怎么矩阵加速?
首先我们发现
然后我们建立一个
我们再根据刚刚推导的转移关系构建转移矩阵
如何构建?
将滚调
-
A_{1,i}=A_{1,k}\sum_kg_{k,i}-B_{1,i} -
B_{1,i}=A_{1,i}\sum_k(g_{i,k}-1)
直观但不严谨的表示:
-
A'=A\times g + B\times(-1) -
B'=A\times (g-1)+B\times0
如果还是没懂,请看下图
| T | 1 | 2 | ... | n | n+1 | n+2 | ... | n+n |
|---|---|---|---|---|---|---|---|---|
| 1 | ... | 0 | .. | 0 | ||||
| 2 | ... | 0 | ... | 0 | ||||
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| n | ... | 0 | 0 | ... | ||||
| n+1 | -1 | 0 | ... | 0 | 0 | 0 | ... | 0 |
| n+2 | 0 | -1 | ... | 0 | 0 | 0 | ... | 0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| n+n | 0 | 0 | ... | -1 | 0 | 0 | ... | 0 |
总复杂度:
代码已经过可读性修改:
void solve(){
cin>>n>>m>>t>>st>>ed;
st++,ed++;
for1(i,1,m){
int u,v;
cin>>u>>v;
u++,v++;
g[u][v]++,g[v][u]++;
}
T.row=T.col=n*2;
for1(i,1,n){
T.t[i+n][i]=T.t[i][i+n]=-1;
for1(j,1,n)
T.t[i][i+n]+=g[i][j],T.t[i][j]=g[i][j];
}
F.row=1,F.col=n*2;
for1(i,1,n)
F.t[1][i]+=g[st][i],F.t[1][st+n]+=g[st][i];
F=F*(T^(t-1));
cout<<F.t[1][ed];
return ;
}