#include #include typedef long long ll; using namespace std; ll dp[2][105][5005]; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); //一定是0好串1 或 好串+好串,区间DP //但是需要O(n^6)枚举两侧长度和逆序对数啊? //不要用区间dp计数!dp[n][h][k],n长,0比1多h,逆序对k int n;ll m;cin>>n>>m; memset(dp,0,sizeof(dp)); dp[0][0][0]=1; for(int i=1;i<=2*n;i++){ for(int k=0;k<=n*(n-1)/2;k++){ dp[1][0][k]=dp[0][1][k]; //一样多肯定是补了1 for(int h=1;h<=min(n,i);h++){ int one=(i-h)/2; dp[1][h][k]=0; if(h+1<=n) dp[1][h][k]=(dp[1][h][k]+dp[0][h+1][k])%m; //补1 if(k>=one) dp[1][h][k]=((dp[1][h][k]+dp[0][h-1][k-one])%m+m)%m; //补0 } } for(int k=0;k<=n*(n-1)/2;k++){ for(int h=0;h<=min(n,i);h++){ dp[0][h][k]=dp[1][h][k]; } } } for(int k=0;k<=n*(n-1)/2;k++){ cout<