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;
}