• 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
    ");
    15 #define pn printf("
    ");
    16 #define pk printf(" ");
    17 #define p(n) printf("%d",n);
    18 #define pln(n) printf("%d
    ",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

      

  • 相关阅读:
    Marshal's Confusion III(快速幂)
    两种筛素数的方法
    B
    HDU 1563 【Find your present!】
    HDU 2044【一只小蜜蜂】
    HDU 2153 仙人球的残影
    NYOJ 49 【开心的小明】
    最小的回文数
    Google Code Jam 2014资格赛【Problem A. Magic Trick】
    携程编程大赛 (预赛第二场)第一题【剪刀石头布】
  • 原文地址:https://www.cnblogs.com/Kidgzz/p/10201265.html
Copyright © 2020-2023  润新知