solution:
设(dp_{a,f_1,b,f_2,c})表示从a到b,使用最大的按钮编号$leq $c。
- (f_1)表示是否对第一个按的有要求,如果有,则(a=s)需要先按下(b_s)。
- (f_2)表示是否对最后一个有要求,如果有,则(b=t),最后要按下(b_t)。
先考虑简单的情况:(f_{1}=f_{2}=0),以下用(dp_{a,b,c})代替(dp_{a,0,b,0,c,0})。
有两种转移:
-
按的最大的<c,则(dp_{a,b,c}+=dp_{a,b,c-1})
-
按的最大的=c, 则(dp_{a,b,c}+=sum _{r}(sum _{i,e[i,r]=1} dp_{a,i,c-1})*(sum _{j,e[r,j]=1}dp_{j,b,c-1})),显然这两个部分都是可以(O(N^4))预处理的。设(g_{a,r,c}=sum_{e[b,r]=1} dp_{a,b,c},f_{r,a,c}=sum _{e[r,b]=1} dp_{b,a,c})。则(dp_{a,b,c}+=sum _{r} g_{a,r,c-1} imes f_{r,b,c-1})。
这部分的转移是(O(N^4))的。
可以发现(f_1=f_2=0)的部分对于所有的询问都是互不影响的。所以我们可以先(O(N^4))的算出这些答案。
然后我们再考虑(f_1=1)的情况,可以发现有用的状态的a一定等于s。同理(f_2=1)的时候,有用状态的b等于t。
所以对于每一个询问,有用状态是(O(N^2K))级别的。
总时间复杂度为(O(N^3*K+N^2*Q*K))
/*
{
######################
# Author #
# Gary #
# 2020 #
######################
*/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
// int x=0;
// char ch=getchar();
// while(ch<'0'||ch>'9'){
// ch=getchar();
// }
// while(ch>='0'&&ch<='9'){
// x=(x<<1)+(x<<3)+(ch^48);
// ch=getchar();
// }
// return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
int n,k,q;
const int MAXN=60+1;
int dp[2][2][MAXN][MAXN][MAXN],g[2][MAXN][MAXN][MAXN],f[2][MAXN][MAXN][MAXN];
bool e[MAXN][MAXN];
const int MOD=1e9+7;
void add(int& x,int y){
x+=y;
if(x>=MOD) x-=MOD;
}
void normal(){
rb(c,1,k){
rb(r,1,n){
rb(a,1,n)rb(b,1,n){
if(e[b][r]){
add(g[0][r][a][c],dp[0][0][a][b][c-1]);
}
if(e[r][a]){
add(f[0][r][b][c],dp[0][0][a][b][c-1]);
}
}
add(f[0][r][r][c],1);
add(g[0][r][r][c],1);
}
rb(i,1,n) rb(j,1,n){
dp[0][0][i][j][c]=dp[0][0][i][j][c-1];
rb(r,1,n) add(dp[0][0][i][j][c],1ll*g[0][r][i][c]*f[0][r][j][c]%MOD);
}
}
}
int bs,s,bt,t;
int calc(){
rep(i,2) rep(j,2) if(i+j) memset(dp[i][j],0,sizeof(dp[i][j]));
memset(g[1],0,sizeof(g[1]));
memset(f[1],0,sizeof(f[1]));
rb(c,1,k){
rb(r,1,n){
rb(i,1,n){
if(e[i][r]){
add(g[1][r][s][c],dp[1][0][s][i][c-1]);
}
if(e[r][i]){
add(f[1][r][t][c],dp[0][1][i][t][c-1]);
}
}
}
if(c==bs){
add(g[1][s][s][c],1);
}
if(c==bt){
add(f[1][t][t][c],1);
}
add(dp[1][1][s][t][c],dp[1][1][s][t][c-1]);
rb(i,1,n){
add(dp[1][0][s][i][c],dp[1][0][s][i][c-1]);
add(dp[0][1][i][t][c],dp[0][1][i][t][c-1]);
rb(r,1,n){
add(dp[1][0][s][i][c],1ll*g[1][r][s][c]*f[0][r][i][c]%MOD);
add(dp[0][1][i][t][c],1ll*g[0][r][i][c]*f[1][r][t][c]%MOD);
}
}
rb(r,1,n)
add(dp[1][1][s][t][c],1ll*g[1][r][s][c]*f[1][r][t][c]%MOD);
}
return dp[1][1][s][t][k];
}
int main(){
scanf("%d%d%d",&n,&k,&q);
rb(i,1,n) rb(j,1,n){
char c;
cin>>c;
e[i][j]=c-'0';
}
normal();
rb(T,1,q){
scanf("%d%d%d%d",&bs,&s,&bt,&t);
printf("%d
",calc());
}
return 0;
}
/*
6 20 5
110101
011001
001111
101111
111010
000001
2 5 2 5
6 1 5 2
3 4 8 3
9 3 3 5
5 1 3 4
*/