Educational Codeforces Round83D.Count the Arrrays: 콤보

8218 단어 codeforces
아주 재밌는 질문입니다!이런 고찰은 매우 재미있다.
https://codeforces.com/contest/1312/problem/D
hitonanode의 Submit은 매우 이해하기 쉽고 참고 가치가 있다.
https://codeforces.com/contest/1312/submission/72804437

제목의 뜻


하나 이상의 정수 요소로 구성된 배열을 제시했다.그 밖에 정수 m도 제시한다.
b. 이 배열은 i번째 최대치를 가지고 왼쪽은 (0으로) 단조로워지고 오른쪽은 단조로워진다.다음은 최고치라고 한다.
c. 이 배열은 숫자가 같은 것만 맞다.
d. 이런 몇 열은 몇 열입니까?mod로 서술하다.

예제


몇 달러 n=4, m=5를 고려해 보세요.
- $[1,2,3,1]$
- $[1,4,2,1]$
- $[2,4,3,2]$
단조로운 감소, 단조로운 증가를 조건으로 다음과 같은 값은 지속될 수 없다.
- $[2,2,3,1]$
또 제목별로 보면 다음과 같이 단조로운 증가·감소 구간이 없는 수열도 NG다.
- $[1,2,3,4]$
- $[4,3,2,1]$

전환 문제



위에는 n=6, i는 7의 그림이다.(i는 최고치이지 m 자체가 아니다(후술)
  • 피크 값 i가 있음(그림의 검은색 7)

  • (이 값이 가장 크기 때문에) i-1 이하의 숫자 j를 선택하면 이 값은 최고치 정도에 설정됩니다.(그림의 녹색)
  • 단조로운 증가 구간과 단조로운 감소 구간에 두 번 이상 같은 숫자가 존재할 수 없기 때문

  • n-3개의 j가 아닌 i-1 이하의 숫자(즉, i-2 중 3개를 선택)(그림에서 빨간색)
  • 최고치 k와 2쌍의 숫자 j를 선택했기 때문에 n 길이의 배열에 들어가야 하는 요소는 n-3개이다.

  • 피크 값의 오른쪽에 할당할지 왼쪽에 할당할지 선택합니다.(그림의 노란색)
  • 위에서 말한 바와 같이 봉의 좌우에 최소한 하나의 숫자를 입력해야 하지만 이 숫자들은 모두 오른쪽에 놓거나 왼쪽에 놓을 수 있다.j를 선택할 때 좌우에 최소한의 숫자가 있기 때문에 좌우의 원소는 최소한 하나를 보존한다.
  • 이 계산들은 i가 $(n-1)달러에서 $m까지만 하면 된다.만약 i가 n-2(이하)라면 숫자를 선택할 수 없습니다
    - 예: n=6 중 i=5면 $[1,5,4,3,2,1] 달러
    - 예: n=6, i=4, 그럼 [1,4,3,2,1로 갈까요?되다

    이루어지다


    $$\sum_{i=(n-1)}^{m} (i-1)\cdot {}_{(i-2)}C _{(n-3)}\cdot 2^{(n-3)}$$
    끝났어!대단하다
  • $n, r$2\cdot10^{5}달러 정도의mod의 $nCr$for가 회전하기 때문에 각종 결과를 미리 캐시하지 않으면 TLE를 진행할 수 없습니다.
  • # https://www.planeta.tokyo/entry/5195/
    mod = 998244353
    
    def cmb(n, r, p):
        if (r < 0) or (n < r):
            return 0
        r = min(r, n - r)
        return fact[n] * factinv[r] * factinv[n - r] % p
    
    p = mod
    N = 5 * 10 ** 5  # N は必要分だけ用意する
    fact = [1, 1]
    factinv = [1, 1]
    inv = [0, 1]
    
    for i in range(2, N + 1):
        fact.append((fact[-1] * i) % p)
        inv.append((-inv[p % i] * (p // i)) % p)
        factinv.append((factinv[-1] * inv[-1]) % p)
    
    
    n, m = map(int, input().split())
    res = 0
    import math
    if n == 2:
        print(0)
    else:
        for i in range(n-1, m+1):
            res += (i - 1) * cmb(i - 2, n - 3, mod) * pow(2, n-3, mod)
            res %= mod
        print(res)
    
    

    경품: NG 방법


    다시 말하면 정리하려다가 방향을 잃었다는 것이다.

    좋은 웹페이지 즐겨찾기