【题解】[SNOI2019] 纸牌

$$\rm SNOI2019$$ 纸牌

$$\rm Algorithm · 1$$

$f_{i+1,k,l} = \begin{cases}f_{i,j,k}\cdot (\lfloor \frac{c-s}{3}\rfloor + 1) , s\geq a_{i+1} \\ f_{i,j,k}\cdot (\lfloor \frac{c -(s+3\cdot \lceil \frac{a_{i+1}-s}{3}\rceil )}{3}\rfloor+1) , s< a_{i+1}\end{cases}$

inline int get_v(int x){
x %= 3 ;
if (x == 2) return 1 ;
else if (x == 1) return 2 ; return 0 ;
}
signed main(){
cin >> N >> M >> T, dp[0][0][0] = 1 ;
for (i = 1 ; i <= T ; ++ i) scanf("%lld%lld", &j, &k), Num[j] = k ;
for (i = 1 ; i <= N ; ++ i)
for (j = 0 ; j < 3 ; ++ j)
for (k = 0 ; k < 3 ; ++ k)
for (l = 0 ; l < 3 ; ++ l){
int now = j + k + l, dis ;
if (M < now) continue ;
if (Num[i] > now) dis = Num[i] + get_v(Num[i] - now) ; else dis = now ;
if (dis <= M) dp[i][k][l] = (dp[i][k][l] + dp[i - 1][j][k] * ((M - dis) / 3 + 1)) % Mod ;
}
cout << dp[N][0][0] << endl ; return 0 ;
}


$$\rm Algorithm ·2$$

LL n, m, c, x, y, lx, ly ;
struct matrix{
int b[12][12] ;
void clear(){ memset(b, 0, sizeof(b)) ; }
void reset(){
clear() ;
for (int i = 0 ; i < 10 ; ++ i)
b[i][i] = 1 ;
}
matrix friend operator * (const matrix &a, const matrix &b){
matrix c ; c.clear() ;
for (int i = 0 ; i < 10 ; ++ i)
for (int j = 0 ; j < 10 ; ++ j)
for (int k = 0 ; k < 10 ; ++ k)
c.b[i][j] = (c.b[i][j] + 1ll * a.b[i][k] * b.b[k][j] % Mod) % Mod ;
return c ;
}
}ans, unit, tmp ;

matrix expow(matrix a, LL b){
matrix res ; res.reset() ;
while (b){
if (b & 1)
res = res * a ;
a = a * a ; b >>= 1 ;
}
return res ;
}
signed main(){
cin >> n >> c >> m ; LL q ; //cout << n << endl ;
ans.b[0][0] = 1 ; int i, j, k, l ;
for (i = 0 ; i < 3 ; ++ i)
for (j = 0 ; j < 3 ; ++ j)
for (k = 0 ; k < 3 ; ++ k)
if (i + j + k <= c)
unit.b[i * 3 + j][j * 3 + k] = (c - (i + j + k)) / 3ll + 1ll ;
for (i = 1 ; i <= m ; ++ i){
scanf("%lld%lld", &x, &y), tmp.clear() ;
ans = ans * expow(unit, x - lx - 1) ;
for (j = 0 ; j < 3 ; ++ j)
for (k = 0 ; k < 3 ; ++ k)
for (l = 0 ; l < 3 ; ++ l){
int s = j + k + l ;
if (s < y) s = y + ((s - y) % 3 + 3) % 3 ;
if (s <= c) tmp.b[j * 3 + k][k * 3 + l] = (c - s) / 3ll + 1ll ;
}
lx = x, ly = y, ans = ans * tmp ;
}
ans = ans * expow(unit, n - (LL)lx), cout << ans.b[0][0] << endl ; return 0 ;
}

posted @ 2020-01-08 10:22  _Orchidany  阅读(289)  评论(0编辑  收藏  举报