https://www.luogu.com.cn/problem/P9366
构造循环矩阵,考虑反射容斥和将军饮马
考虑二维不太好做,我们曼哈顿距离转切比雪夫距离,变成一维的情况。
由于棋盘是正方形的,所以循环长度为 2 n + 4 2n+4 2n+4。用多项式快速幂预处理,询问记得考虑正负两个方向。
auto kuai(int T) {
if(T==0) return atcoder :: Poly({1});
auto p = kuai(T/2);
p *= p;
for(int i=M; i < p.size(); ++i) p[i-M]+=p[i];
p = p.modxk(M);
if(T % 2 == 0) return p;
p = p.mulxk(1) + p.mulxk(M-1);
for(int i=M; i < p.size(); ++i) p[i-M]+=p[i];
p = p.modxk(M);
return p;
}
signed main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
// T=read();
// while(T--) {
//
// }
n=read(); T=read(); q=read();
N=2*(n+1)+2; M=2*N;
auto res = kuai(T);
auto Go = [&] (int u0, int v0, int u1, int v1) {
int dx = ( ((u1+v1) - (u0+v0)) % M + M)%M;
int dy = ( ((u1-v1) - (u0-v0)) % M + M)%M;
// printf("%lld %lld | %lld %lld\n", res[dx].x, res[dy].x, res[(dx+N)%M], res[(dy+N)%M]);
return res[dx] * res[dy] + res[(dx+N)%M] * res[(dy+N)%M];
};
while(q--) {
u0 = read(); v0 = read();
u1 = read(); v1 = read();
auto ans = Go(u0, v0, u1, v1);
ans -= Go(u0, v0, N - 2 - u1, v1);
ans -= Go(u0, v0, u1, N - 2 - v1);
ans += Go(u0, v0, N - 2- u1, N - 2 - v1);
printf("%lld\n", ans.x);
}
return 0;
}