题意

为对排列 跑单调栈后剩下的元素个数, 求所有长度为 的排列 ^3 之和

solution

考虑递推, 令 为长度为 的所有排列中 = 的个数 我们的答案就是

因为 一定在长度为 的栈中,且 前的数一定无贡献 故 考虑选一些数放到 后 , n+1 前的所有数可任意排列 则可知

----(1)

--------------------------(2)

由(1)(2)得

把 (i+1)^3分解

其实就是 排列 (即总方案数)

接下来我们只需要想想如何 转移

重复上面的步骤可以知道

由此我们得出了递推式

;

预处理所有即可

AC代码:

#include<bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <assert.h>
#include <numeric>
#include <iomanip>
#include <vector>
#include <array>
#include <cmath>
#include <map>
#include <set>
#include<queue>

#ifdef LOCAL
#include "debug.h"
#else
#pragma GCC optmize(2)
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") //// avx / SSE ////
#define Preproce()
#define Endproce()
#define Debug(...)
#endif
#define llng long long
#define int long long

using namespace std;
const int MAX=5e5+9;
const int mod=998244353,inv2=499122177;
int ji[MAX],g[MAX],h[MAX],s[MAX];
void pre(){
    ji[0]=1;
    for(int i=1;i<=5e5;i++){
        ji[i]=ji[i-1]*i;
        ji[i]%=mod;
        h[i]=i*h[i-1]+ji[i-1];
        h[i]%=mod;
        g[i]=i*g[i-1]+2*h[i-1]+ji[i-1];
        g[i]%=mod;
        s[i]=i*(s[i-1])+3*g[i-1]+3*h[i-1]+ji[i-1];
        s[i]%=mod;
    }
}

void solve(){
    int n;
    cin>>n;
    cout<<s[n]<<"\n";
    //for(int i=1;i<=100;i++){
        //cout<<ji[i]<<" "<<h[i]<<" "<<g[i]<<" "<<s[i]<<"\n";
    //}
}
signed main(){
	Preproce();

    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    pre();
    int t1=1;
    cin>>t1;
    while(t1--)
    solve();

    cout.flush();

	Endproce();

    return 0;
}