AtCoder AGC036C GP 2 (composition count)

Topic Link

https://atcoder.jp/contests/agc036/tasks/agc036_c

answer

Finally have time to make up agc036 of the subject.
This question is not difficult to significantly ...... I too thought out dishes on the test

Is first converted at Title: A sequence may be generated when the press operation subject and only if its length \ (N \) , the sum of \ (3M \) , and the maximum number of not more than \ (2M \) , odd number the number does not exceed \ (M \) .
necessity is clear, easy to prove the adequacy of induction.

Then consider how count: the second condition is not considered, the definition of \ (f (n, m, k) \) represents the length of \ (n-\) the sum of \ (m \) an odd number of not more than \ (K \) th the number of programs, the number of enumerated odd \ (I \) , and even for the remaining \ (. 1-m \) , there are \ (f (n, m, k) = \ sum ^ {k} _ I {\ equiv m (\ MOD 2)} {n-\ the Choose {I} \ {mi The FRAC} + {n-2}. 1-\}. 1-n-the Choose \) .
consider the second condition, the complement conversion, the maximum the number is greater than \ (2M \) means that all the rest of the number is less than \ (M \) , then do not write out the formula and then push no brains formula! Fixing the position of the maximum number of \ (1 \) , for subtracting the first number \ (2M \) (this is an even number that it does not affect the odd conditions), is required \ (and the number of \) M $, the first number is greater than \ (0 \) , a total of not more than \ (M \) th odd number of programs. The limited number of odd because so enumeration is very troublesome, it is set to fix the conversion! Converted to \ ((N-1) \ ) number and for the \ (M \)And not more than odd \ (M \) a.

So the final answer is \ (F (N, 3M, M) -N (F (N, M, M) -f (. 1-N, M, M)) \) .

Time complexity \ (O (N + M) \) .

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<iostream>
#define llong long long
using namespace std;

inline int read()
{
    int x=0; bool f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
    for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
    if(f) return x;
    return -x;
}

const int N = 2e6;
const int P = 998244353;
llong fact[N+3],finv[N+3];

llong quickpow(llong x,llong y)
{
    llong cur = x,ret = 1ll;
    for(int i=0; y; i++)
    {
        if(y&(1ll<<i)) {y-=(1ll<<i); ret = ret*cur%P;}
        cur = cur*cur%P;
    }
    return ret;
}
llong comb(llong x,llong y) {return x<0||y<0||x<y ? 0ll : fact[x]*finv[y]%P*finv[x-y]%P;}

llong calc(llong n,llong m,llong k)
{
    llong ret = 0ll;
    for(int i=0; i<=k; i++)
    {
        if((m-i)&1) continue;
        llong tmp = comb(n,i)*comb(((m-i)>>1)+n-1,n-1)%P;
        ret = (ret+tmp)%P;
    }
//  printf("calc %lld %lld %lld=%lld\n",n,m,k,ret);
    return ret;
}

int n,m;

int main()
{
    fact[0] = 1ll; for(int i=1; i<=N; i++) fact[i] = fact[i-1]*i%P;
    finv[N] = quickpow(fact[N],P-2); for(int i=N-1; i>=0; i--) finv[i] = finv[i+1]*(i+1)%P;
    scanf("%d%d",&n,&m);
    llong ans = calc(n,3*m,m);
    ans = (ans-n*(calc(n,m,m)-calc(n-1,m,m)+P)%P+P)%P;
    printf("%lld\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/suncongbo/p/11297768.html