题解:CF2145F Long Journey
MaxBlazeResFire · · 题解
记
记
这样,我们把
矩阵快速幂即可。剩下的余块可以直接查表,复杂度
代码里写的是 dijkstra。
::::success[Code]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF (ll)1e18
const int N = 10;
const int V = 2520;
int n,a[N],b[N],vis[N][V + 1];
ll dis[N][N][V + 1],m;
struct node{
int ti,pos; ll dis;
inline bool operator <( const node &b ) const{
return b.dis < dis;
}
};
inline bool judge( int tim , int S ){ return S % a[tim] != b[tim]; }
vector< pair<int,int> > E[10][V + 1];
priority_queue<node> Q;
inline void dijkstra( int st ){
for( int i = 0 ; i < n ; i ++ )
for( int j = 0 ; j <= V ; j ++ ) dis[st][i][j] = INF,vis[i][j] = 0;
dis[st][st][0] = 0; Q.push( node{ st , 0 , 0 } );
while( !Q.empty() ){
node u = Q.top(); Q.pop();
if( vis[u.ti][u.pos] ) continue;
vis[u.ti][u.pos] = 1;
for( pair<int,int> v : E[u.ti][u.pos] ){
if( dis[st][v.first][v.second] > u.dis + 1 ){
dis[st][v.first][v.second] = u.dis + 1;
if( !vis[v.first][v.second] ) Q.push( node{ v.first , v.second , dis[st][v.first][v.second] } );
}
}
}
}
inline void clear(){
for( int i = 0 ; i < n ; i ++ ) a[i] = b[i] = 0;
for( int st = 0 ; st < n ; st ++ )
for( int i = 0 ; i < n ; i ++ )
for( int j = 0 ; j <= V ; j ++ ) vis[i][j] = dis[st][i][j] = 0,E[i][j].clear();
}
struct matrix{
ll a[N][N];
matrix(){
for( int i = 0 ; i < N ; i ++ )
for( int j = 0 ; j < N ; j ++ ) a[i][j] = INF;
}
inline void build(){
for( int i = 0 ; i < N ; i ++ )
for( int j = 0 ; j < N ; j ++ ) a[i][j] = ( i == j ) ? 0 : INF;
}
inline matrix operator *( matrix B ){
matrix C;
for( int i = 0 ; i < N ; i ++ )
for( int j = 0 ; j < N ; j ++ )
for( int k = 0 ; k < N ; k ++ )
C.a[i][j] = min( C.a[i][j] , a[i][k] + B.a[k][j] );
return C;
}
};
inline matrix fp( matrix A , ll p ){
matrix res; res.build();
while( p ){
if( p & 1 ) res = res * A;
A = A * A;
p >>= 1;
}
return res;
}
inline void solve(){
scanf("%d%lld",&n,&m);
for( int i = 1 ; i < n ; i ++ ) scanf("%d",&a[i]); scanf("%d",&a[0]);
for( int i = 1 ; i < n ; i ++ ) scanf("%d",&b[i]); scanf("%d",&b[0]);
for( int i = 0 ; i < n ; i ++ ){
for( int j = 0 ; j < V ; j ++ ){
int nxt = ( i + 1 ) % n;
if( judge( nxt , j + 1 ) ) E[i][j].emplace_back( make_pair( nxt , j + 1 ) );
if( judge( nxt , j ) ) E[i][j].emplace_back( make_pair( nxt , j ) );
}
}
for( int i = 0 ; i < n ; i ++ ) dijkstra( i );
matrix R,F;
for( int i = 0 ; i < n ; i ++ )
for( int j = 0 ; j < n ; j ++ ) R.a[i][j] = dis[i][j][V];
for( int i = 1 ; i < n ; i ++ ) F.a[0][i] = INF; F.a[0][0] = 0;
F = F * fp( R , m / V );
ll Ans = INF;
for( int i = 0 ; i < n ; i ++ )
for( int j = 0 ; j < n ; j ++ ) Ans = min( Ans , F.a[0][i] + dis[i][j][m % V] );
if( Ans == INF ) Ans = -1;
printf("%lld\n",Ans);
clear();
}
signed main(){
int testcase; scanf("%d",&testcase);
while( testcase -- ) solve();
return 0;
}
::::