当x!=y时,这个限制条件是确定的,可以枚举总通过数,用组合数计算,当x==y时,这个限制条件表示前x个全部通过或后x个全部通过,只有最大的x有用,可以用容斥计算。
#include<bits/stdc++.h> const int P=998244353; int T,n,m,pp[3],C[5007][5007]; struct pos{ int x,y,t; bool operator<(pos p)const{return x<p.x;} }ps[3][1077]; void ins(pos p){ for(int i=0;i<3;++i)ps[i][pp[i]++]=p; } int cal(int w,int m){ pos*a=ps[w]; int ap=pp[w],s=1; for(int i=1;i<ap;++i){ int v1=a[i].x-a[i-1].x,v2=a[i].y-a[i-1].y+(a[i].t-a[i-1].t)*m; if(v2<0||v2>v1)return 0; s=1ll*s*C[v1][v2]%P; } return s; } int main(){ C[0][0]=1; for(int i=0;i<5000;++i){ for(int j=0;j<=i;++j){ (C[i+1][j]+=C[i][j])%=P; (C[i+1][j+1]+=C[i][j])%=P; } } for(scanf("%d",&T);T;--T){ scanf("%d%d",&n,&m); int mx=-1; pp[0]=pp[1]=pp[2]=0; ins((pos){0,0,0}); ins((pos){n,0,1}); for(int i=0,a,b;i<m;++i){ scanf("%d%d",&a,&b); if(a>b)ins((pos){a,b,0}); else if(a<b)ins((pos){n-b,-a,1}); else{ if(a>mx)mx=a; } } if(~mx){ ps[0][pp[0]++]=(pos){n-mx,-mx,1}; ps[1][pp[1]++]=(pos){mx,mx,0}; ps[2][pp[2]++]=(pos){mx,mx,0}; ps[2][pp[2]++]=(pos){n-mx,-mx,1}; } for(int i=0;i<3;++i)std::sort(ps[i],ps[i]+pp[i]); int ans=0; for(int i=0;i<=n;++i){ int sgn[]={1,1,-1}; for(int j=0;j<3;++j){ ans=(ans+cal(j,i)*sgn[j])%P; } } printf("%d\n",(ans+P)%P); } return 0; }