题解
看对题目!
首先我们可以把答案看成对于被经过的格子,最后经过的是第几天的总和
对于 $n>1,m>1$ 的时候,如果 $kge nm$ ,那说明你可以现在原地蹲着,等到最后的时候找一条路走满这 $nm$ 个格子,考虑到一个网格图中如果 $n,m$ 都是奇数,那么对于一个格子 $(x,y)$ ,如果 $x+y$ 是偶数那它就存在哈密顿路径,所以如果一开始你在 $(x,y)$ 且 $x+y$是奇数的格子上的话,你可以趁第一天下午溜过去然后蹲着;如果 $n,m$ 有一个是偶数,那图中存在哈密顿回路,因此答案就是 $k-nm+1+...+k$ 。如果 $k<nm$ 的话,那就直接走就好了,答案就是 $1+...+k$
对于 $n=1$ 的情况,假设 $v=min(y,m-y+1)$ 。如果 $m-v+1 ge k$ 的话,那就直接走就好了,答案就是 $1+...+k$ ,如果 $k ge m+m-v-1$ 的话说明你可以先往小的方向走然后蹲着,等到最后再出来,否则的话你就可以先往小的方向走几步,然后再往大的方向走即可
代码
#include <bits/stdc++.h> #define LL long long using namespace std; const LL P=998244353; int T;LL n,m,k,X,Y; LL C(LL l,LL r){ return (l+r)%P*((r-l+1)%P)%P*((P+1)>>1)%P; } void work(){ scanf("%lld%lld%lld%lld%lld",&n,&m,&X,&Y,&k); if (n>1 && m>1) printf("%lld ",C(max(k-n*m,0ll)+1,k)); else{ if (m==1) swap(n,m),swap(X,Y);Y=min(Y,m-Y+1); if (m-Y+1>=k) printf("%lld ",C(1,k)); else if (k>=m+m-Y-1) printf("%lld ",C(k-m+1,k)); else printf("%lld ",C((k+Y-m+1)/2,k)); } } int main(){ for (scanf("%d",&T);T--;work()); return 0; }