D. New Year and the Permutation Concatenation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Let nn be an integer. Consider all permutations on integers 11 to nn in lexicographic order, and concatenate them into one big sequence pp . For example, if n=3n=3 , then p=[1,2,3,1,3,2,2,1,3,2,3,1,3,1,2,3,2,1]p=[1,2,3,1,3,2,2,1,3,2,3,1,3,1,2,3,2,1] . The length of this sequence will be n⋅n!n⋅n! .
Let 1≤i≤j≤n⋅n!1≤i≤j≤n⋅n! be a pair of indices. We call the sequence (pi,pi+1,…,pj−1,pj)(pi,pi+1,…,pj−1,pj) a subarray of pp . Its length is defined as the number of its elements, i.e., j−i+1j−i+1 . Its sum is the sum of all its elements, i.e., ∑jk=ipk∑k=ijpk .
You are given nn . Find the number of subarrays of pp of length nn having sum n(n+1)2n(n+1)2 . Since this number may be large, output it modulo 998244353998244353 (a prime number).
Input
The only line contains one integer nn (1≤n≤1061≤n≤106 ), as described in the problem statement.
Output
Output a single integer — the number of subarrays of length nn having sum n(n+1)2n(n+1)2 , modulo 998244353998244353 .
Examples
Input
Copy
3
Output
Copy
9
Input
Copy
4
Output
Copy
56
Input
Copy
10
Output
Copy
30052700
Note
In the first sample, there are 1616 subarrays of length 33 . In order of appearance, they are:
[1,2,3][1,2,3] , [2,3,1][2,3,1] , [3,1,3][3,1,3] , [1,3,2][1,3,2] , [3,2,2][3,2,2] , [2,2,1][2,2,1] , [2,1,3][2,1,3] , [1,3,2][1,3,2] , [3,2,3][3,2,3] , [2,3,1][2,3,1] , [3,1,3][3,1,3] , [1,3,1][1,3,1] , [3,1,2][3,1,2] , [1,2,3][1,2,3] , [2,3,2][2,3,2] , [3,2,1][3,2,1] .
Their sums are 6 ,6, 7 ,6 ,7,5,6,6, 8 , 6 , 7 , 5 , 6 , 6 , 7 , 6 . As n(n+1)/2=6 , the answer is 9 .
題意:給你一個數n,讓你求在n的全排列依次排列的序列中找到多少個區間滿足區間長度爲n,該區間內數的和爲n*(n+1)/2。
思路:很容易想到,全排列中的每一個排列的和就是n*(n+1)/2,全排列有n!個,然後就是兩個相鄰排列之間可以組合的了,我們用一個固定長度爲n的滑動窗口來類比所選區間,當窗口向右移動時,左邊每出去一個數右邊就會進去一個數,想要區間和爲 n*(n+1)/2那麼區間內所數必須是(1~n)的全排列,因爲是全排列順序排列,所以只可能是出去和進去的數是相同的(有多個的話這多個數順序也必須相同的,比如:....,45 321,54123,45 123 和123 45都滿足和爲15 但是是順序的全排列這是不可能出現的),終上所述只要兩個相鄰的全排列相同前綴的就可以滿足條件,我們有假設長度爲i的相同前綴,有多少長度就可以分多少個區間出來,還是由於是全排列,所以這i個也是全排列,有A(n,i)選擇,剩下後面的n-i個數還是全排列,最後要確保不重不漏,確保只有長度嚴格爲i的前綴相同,那麼在相鄰兩個排列中第i+1個必須不同,所以第i+1位一定是剩下n-i箇中的一個,需要的是兩個相鄰的所以有n-i-1中可行的兩個相鄰排列。最後三者相乘取sigma,得到結果,說的比較生硬,集體見代碼。比賽的時候我真的差點就推出來了。
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<iterator>
#include<set>
#include<map>
#include<bitset>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=1e6+5;
const int inf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
const int mod=998244353;
const double e=exp(1.0);
const double pi=acos(-1);
const double eps=1e-6;
int gcd(int a,int b)
{
if(b==0)return a;
return gcd(b,a%b);
}
ll quick_pow(ll a,int n)
{
ll ans=1;
while(n)
{
if(n&1)ans=(ans*a)%mod;
n/=2;
a=(a*a)%mod;
}
return ans;
}
ll fac[maxn],inv[maxn];
ll C(ll n,ll m)
{
return ((fac[n]*inv[m])%mod*inv[n-m])%mod;
}
int main()
{
fac[0]=1ll;
fac[1]=1ll;
inv[1]=1ll;
for(int i=2;i<maxn-2;i++)
{
fac[i]=fac[i-1]*i%mod;
inv[i]=quick_pow(fac[i],mod-2);
}
int n;
while(scanf("%d",&n)!=EOF)
{
ll ans=fac[n];
for(int i=1;i<=n-2;i++)//相鄰的兩個排列最後兩個數一定是不同的
ans=(ans+i*C(n,i)%mod*fac[i]%mod*(n-i-1)%mod)%mod;
cout<<ans<<endl;
}
return 0;
}