1. 程式人生 > >Codeforces 1091D New Year and the Permutation Concatenation 找規律,數學 B

Codeforces 1091D New Year and the Permutation Concatenation 找規律,數學 B

Codeforces 1091D New Year and the Permutation Concatenation

   https://codeforces.com/contest/1091/problem/D

題目:

    Let n be an integer. Consider all permutations on integers 1 to n in lexicographic order, and concatenate them into one big sequence p. For example, if n=3, then 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!be a pair of indices. We call the sequence (pi,pi+1,…,pj−1,pj) a subarray of pp. Its length is defined as the number of its elements, i.e., j−i+1. Its sum is the sum of all its elements, i.e., ∑jk=ipk.

    You are given n. Find the number of subarrays of p of length n having sum n(n+1)/2. Since this number may be large, output it modulo 998244353 (a prime number).

Input

    The only line contains one integer n (1≤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)/2, modulo 998244353.

Examples

Input1

3

Output1

9

Input2

4

Output2

56

Input3

10

Output3

30052700

Note

  

    In the first sample, there are 16 subarrays of length 3. In order of appearance, they are:

    [1,2,3], [2,3,1], [3,1,3], [1,3,2], [3,2,2] [2,2,1], [2,1,3], [1,3,2], [3,2,3], [2,3,1], [3,1,3], [1,3,1], [3,1,2], [1,2,3], [2,3,2], [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,初始值為1的連續遞增的數列進行全排列然後排在一塊,再找其中連續的n個數,要求這n個數必須是1-n。

  題意就是這樣那麼就分析:

  暴力,呵呵呵呵,祝你好運

  看到只輸入一個數n,第一反應就是oeis

  

  無果,遂自尋規律

  此處應該有規律

1~10是
1 2 9 56 395 3084 26621 253280 2642391 30052700

  當然這個在一開始做的時候是絕對絕對不知道的

  於是手推

  推大概n=5的時候395還沒有太大的問題,分成第一個數字是12345可以分成五份,然後用全排列打個小程式,看看規律

  首先一個很顯然的事實:

  當全排列第一個數字是1和全排列第一個數字是2的湊在一塊,是肯定無法實現1-n的排列的

  所以我們可以把整體分為n份,此為第一個結論

  然後分析每一塊

  先以n=3開始

  全排列是

  123132

  顯然123 132 是兩個,也就是組成這個大數列P的是肯定必須都滿足條件

  然後就是231,此為第一個全排列的第二個數開始,這是重中之重

  第二個全排列的第二個數後面沒有後繼的數,遂作罷

  當n=4時,

  1234 1243 1324 1342 1423 1432

  首先顯然的是6個

  其次就是每個全排列的第二個數和後面的n-1個數組成的都是成立的

  這些是5個

  然後每個全排列的第三個數開始的長度為n的數列成立的是3個

  這時候可能會有一絲絲思路,但不明確

  當n=5的時候

  寫出來有點小多啊。。。。

  那就用程式跑

  擷取我輸出的結果

  

51234
51243
51324
51342
51423
51432
52134
52143
52314
52341
52413
52431
53124
53142

  首先的24個是跑不了

  然後接下來的23也跑不了

  再往下看,,就有些神奇了

  此時應該關注每個全排列的第三個數

  第三個數和第四第五個數,用豎著看的方式,會發現當前兩個數固定,就是後面在進行全排列!(廢話這是全排列的性質)

  那麼我們可以分析出來這24箇中,5個成立的,1個不成立的,5個成立的,1個不成立的

  咦居然有周期

  試試第四個數

  1,1,1,1,1

  也就是成立和不成立交叉著

  那麼和第四個數相匹配,那是什麼?

  23+1 = 24

   5+1 = 6

  1+1 = 2

  這不就是階乘嗎!

  然後再用心鑽研那麼一點點

  ((n-1)!+(n-1)!*((n-2)!-1)/(n-2)!+(n-1)!*((n-3)!-1)/(n-3)!···)*n

  講真這裡還不如自己手寫一下然後看程式碼

  對了除法取模要用逆元

  

  這道題你要說不會做以後遇到怎麼辦,我只能說多練數學題,培養對數學的感覺,就是這樣

 AC程式碼

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #include <iostream>
 6 #include <string>
 7 #include <time.h>
 8 #include <queue>
 9 #include <string.h>
10 #define sf scanf
11 #define pf printf
12 #define lf double
13 #define ll long long
14 #define p123 printf("123\n");
15 #define pn printf("\n");
16 #define pk printf(" ");
17 #define p(n) printf("%d",n);
18 #define pln(n) printf("%d\n",n);
19 #define s(n) scanf("%d",&n);
20 #define ss(n) scanf("%s",n);
21 #define ps(n) printf("%s",n);
22 #define sld(n) scanf("%lld",&n);
23 #define pld(n) printf("%lld",n);
24 #define slf(n) scanf("%lf",&n);
25 #define plf(n) printf("%lf",n);
26 #define sc(n) scanf("%c",&n);
27 #define pc(n) printf("%c",n);
28 #define gc getchar();
29 #define re(n,a) memset(n,a,sizeof(n));
30 #define len(a) strlen(a)
31 #define LL long long
32 #define eps 1e-6
33 using namespace std;
34 const ll mod = 998244353;
35 ll pow_quick(ll a,ll b){
36     ll r = 1,base = a;
37     while(b){
38         if(b & 1){
39             r *= base;
40             r %= mod;
41         }
42         base *= base;
43         base %= mod;
44         b >>= 1;
45     }
46     return r;
47 }
48 
49 ll a[1000050];
50 int main() {
51     ll n;
52     sld(n)
53     if(n == 1){
54         p(1) pn return 0;
55     }
56     a[1] = 1ll;
57     for(ll i = 2; i <= n; i ++){
58         a[i] = a[i-1]*i;
59         a[i] %= mod;
60     }
61     ll sum = a[n-1];
62     //pld(sum) pn
63     for(ll i = 3; i <= n; i ++){
64         ll x = (a[n-1]*pow_quick(a[i-1],mod-2))%mod;
65         x *= a[i-1]-1;
66         x %=mod;
67         sum += x;
68         sum %= mod;
69     }
70     pld((sum*(n))%mod) pn
71     return 0;
72 }

  程式碼連結:https://codeforces.com/contest/1091/submission/47758982