CF1091D New Year and the Permutation Concatenation

发现答案由所有完整的排列和某些两个相邻的排列构成。
考虑两个相邻排列的贡献。
如果它们的lcp为k的话,画图可发现,此时一共有k个位置可以形成排列。
考虑计算lcp为k的相邻排列有多少对。
发现这个式子是可以推出来的的,枚举lcp求解即可。

#include<iostream>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#define N 2200000
#define L 2000000
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline ll read()
{
	char ch=0;
	ll x=0,flag=1;
	while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
	return x*flag;
}
const ll mo=998244353;
ll ksm(ll x,ll k){ll ans=1;while(k){if(k&1)ans=ans*x%mo;k>>=1;x=x*x%mo;}return ans;}
ll inv(ll x){return ksm(x%mo,mo-2);}
ll fac[N];
int main()
{
	ll n=read();
	fac[0]=1;
	for(ll i=1;i<=n;i++)fac[i]=fac[i-1]*i%mo;
	ll ans=fac[n];
	for(ll i=1;i<n;i++)ans=(ans+(i*fac[n]%mo*inv(fac[n-i])%mo*(n-i-1)%mo))%mo; 
	printf("%lld",(ans%mo+mo)%mo);
	return 0;
}
原文地址:https://www.cnblogs.com/Creed-qwq/p/10222340.html