Fun Count Not Fun#12383

Fun Count Not Fun (Editorial)

When we remove a contiguous subarray of length , the array shrinks, but the relative positions of the remaining elements follow a strict mathematical rule.


1. The Index Invariance

When a subarray of length is removed starting at some index , any element originally at index (where j > i+k) shifts left by exactly units.

2. Defining the Constraints

Let be the initial length and be the removal block size.

3. Transformation to Stars and Bars

To satisfy the modulo condition, we can rewrite each original index as:

i_j = j + a_j \cdot k

Where a_j is the number of -sized blocks skipped or deleted to the left of the j^{th} element.

Substituting this into our ordering constraint (i_j < i_{j+1}):

j + a_j \cdot k < (j+1) + a_{j+1} \cdot k \implies a_j \le a_{j+1}

And for the boundary (i_r \le n):

r + a_r \cdot k \le r + q \cdot k \implies a_r \le q

This reduces the problem to choosing a non-decreasing sequence of integers where each a_j \in [0, q].

4. The Final Formula

This is a classic "Stars and Bars" problem (choosing items from q+1 possible values with replacement). The number of ways is:

\binom{(q+1) + r - 1}{r} = \binom{q+r}{r}

#include <bits/stdc++.h>
using namespace std;
#define ll long long 

const ll mod = 998244353 ;
const ll N = 1e6 + 5; 
vector <ll> factorial(N); 
vector <ll> invfact(N); 
 
ll binpow(ll a , ll b) { 
 ll ans = 1; 
 ll index = a; 
 while (b) { 
  if (b & 1) { 
   ans = (ans * index) % mod; 
  } 
  index = (index * 1LL * index) % mod; 
  b >>= 1; 
 } 
 return ans % mod; 
} 
 
void fillfact() { 
 factorial[0] = 1; 
 for (int i = 1; i < N; i++) { 
  factorial[i] = (factorial[i - 1] * i) % mod; 
 } 
} 
 
void fillinvfact() { 
 invfact[N - 1] = (binpow(factorial[N - 1] , mod - 2)) % mod; 
 for (int i = N - 2; i >= 0; i--) { 
  invfact[i] = ((i + 1) * 1LL * invfact[i + 1]) % mod; 
 } 
} 
 
ll ncr(int n , int r) { 
 if (n < r) return 0; 
 if (n < 0 || r < 0) return 0; 
 ll ans = (factorial[n] * 1LL * invfact[n - r]) % mod; 
 ans = (ans * invfact[r]) % mod; 
 return ans % mod; 
} 

void solve() {
  
  int n , k ;
  cin >> n >> k ;
  int sum = (n % k) ;
  int f = ((n + k - 1) / k) ;
  cout << ncr(sum + f - 1 , sum) << endl ;
    
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    // freopen("output.txt", "w", stdout);
    // freopen("input.txt", "r", stdin);
    int t;
    cin >> t ;
    fillfact() ;
    fillinvfact() ;
    while (t--) {
        solve();
    }
    return 0;
}