正题
题目大意
给出nnn,求一个长度为2n2n2n的由1∼n1\sim n1∼n各两个组成的一个序列使得有一个数的前缀数量不小于任何数字。
解题思路
首先这个数字肯定是第一个数字,这里假设为111,那么要求任意位置111的前缀数量都不小于别的数。
也就是第二个111在任何一个数字的前面,我们考虑枚举第二个1的位置iii,那么对面该位置前方有nnn个数可以放置,方案为P(n,i−2)P(n,i-2)P(n,i−2)。然后对于该位置后方,有2∗n−i2*n-i2∗n−i个数可以放置,但是有n−i+1n-i+1n−i+1个数字有一个重复,所以方案为(2∗n−1)!2n−i+1\frac{(2*n-1)!}{2^{n-i+1}}2n−i+1(2∗n−1)!
所以答案就是n∗∑i=2nP(n,i−2)∗(2∗n−1)!2n−i+1n*\sum_{i=2}^nP(n,i-2)*\frac{(2*n-1)!}{2^{n-i+1}}n∗i=2∑nP(n,i−2)∗2n−i+1(2∗n−1)!
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2e6+10,XJQ=998244353;
ll n,fac[N],z[N],pows[N],ans;
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%XJQ;x=x*x%XJQ;b>>=1;}return ans;
}
int main()
{scanf("%lld",&n);fac[0]=z[0]=pows[0]=1;for(ll i=1;i<=2*n;i++)fac[i]=fac[i-1]*i%XJQ;for(ll i=1;i<=n;i++)z[i]=z[i-1]*(n-i)%XJQ,pows[i]=pows[i-1]*2%XJQ;for(ll i=2;i<=n+1;i++){ans+=z[i-2]*fac[2*n-i]%XJQ*power(pows[n-i+1],XJQ-2)%XJQ;ans%=XJQ;}printf("%lld",ans*n%XJQ);
}