NC223137. 智乃酱的双塔问题
描述
输入描述
第一行输入两个正整数表示高塔的层数,以及询问的次数。第二行输出一个长度大小为的字符串,字符串仅包括。接下来行,每行四个整数,分别表示智乃酱一开始的层数,她想去的层数。当为0时,表示一开始在左边的塔,否则表示一开始在右边的塔。当为0时,表示她的终点为左边的塔,否则表示终点为右边的塔。
输出描述
输出行,每行一个正整数表示方案数对取余数后的结果。
示例1
输入:
4 5 //\ 1 4 0 0 2 4 0 0 2 4 0 1 3 4 0 1 3 4 1 0
输出:
3 2 1 0 1
说明:
C++ 解法, 执行用时: 55ms, 内存消耗: 7664K, 提交时间: 2022-02-18 17:49:40
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll mod = 1e9 + 7; const ll N = 2e5 + 5; struct Matrix { ll mat[2][2]; Matrix() { memset(mat, 0, sizeof(mat)); } Matrix(ll a1, ll a2, ll a3, ll a4) { mat[0][0] = a1; mat[0][1] = a2; mat[1][0] = a3; mat[1][1] = a4; } Matrix inv() { return Matrix(mat[1][1],(mod -mat[0][1])%mod ,(mod - mat[1][0])%mod , mat[0][0]); } Matrix operator * (const Matrix &b) { Matrix c; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) for (int k = 0; k < 2; k++) c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j] % mod) % mod; return c; } } prefix[N]; ll n, m, hs, ht, ps, pt; char c; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; prefix[0] = Matrix(1, 0, 0, 1); for (int i = 1; i < n; i++) { cin >> c; if (c == '/') prefix[i] = prefix[i - 1] * Matrix(1, 1, 0, 1); else prefix[i] = prefix[i - 1] * Matrix(1, 0, 1, 1); } while (m--) { cin >> hs >> ht >> ps >> pt; cout << (prefix[hs - 1].inv() * prefix[ht - 1]).mat[ps][pt] << '\n'; } return 0; }