AGC036C GP 2

Due to the recent training school has been doing for a long time and then questions are how to write a title (

Send blog post to prove I'm alive (in fact, no one cares

It seems not a difficult one count of mind is always a lack of leads will not do this (

First, we can analyze the nature

1. $ \ Sum A_i = 3m $ Obviously

2. $ \ Sum A_i & 1 <= m $ consider our 2 1 1 For a position we can be combined as it is clear that there will be no more than 2 m odd

3. $ max (A_i) <= 2m $ because of an operation to make up a number of still apparent +2

We got three obvious conclusion that we still do not do this problem

Let's consider the first two restrictions we can solve this better enumerate odd number of other $ F (n, m, k) $ n represents the total number of m and there are no more than k odd

The method we can obtain interposer persimmon $ F (n, m, k) = \ sum_ {i = 0} ^ {max (n, k)} C (n, i) * C ((mi) / 2 + n -1, n-1) $ should be better understood

We continue to consider the last restrictions conceivable> 2m number we can not be more than one handpicked $ a_1> 2m $ multiplied by the last n can then make $ a_1 = a_1 - 2m $

Then we became the first two restrictions limit + $ a_1> 0 $ then continue to process $ a_1> 0 $

We found that we can directly make $ n = n-1 $ handpicked $ a_1 = 0 $ is then considered only the first two limits subtraction enough

The final answer is $ F (n, 3m, m) -n (F (n, m, m) -F (n-1, m, m)) $

Then the bound complex of this fact pretreatment $ O (n + m) $

What counts is still good fairy ah.

//Love and Freedom.
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#define ll long long
#define inf 20021225
#define mdn 998244353
#define N 3000001
using namespace std;
int read()
{
    int s=0,f=1; char ch=getchar();
    while(ch<'0' || ch>'9')    {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0' && ch<='9')    s=s*10+ch-'0',ch=getchar();
    return f*s;
}
int fac[N],inv[N];
void upd(int &x,int y){x+=x+y>=mdn?y-mdn:y;}
int ksm(int bs,int mi)
{
    int ans=1;
    while(mi)
    {
        if(mi&1)    ans=1ll*ans*bs%mdn;
        bs=1ll*bs*bs%mdn; mi>>=1;
    }
    return ans;
}
void init(int n)
{
    fac[0]=1;
    for(int i=1;i<=n;i++)    fac[i]=1ll*fac[i-1]*i%mdn;
    inv[n]=ksm(fac[n],mdn-2);
    for(int i=n;i;i--)        inv[i-1]=1ll*inv[i]*i%mdn;
}
int C(int n,int m)
{
    if(n<m)    return 0;
    return 1ll*fac[n]*inv[n-m]%mdn*inv[m]%mdn;
}
int F(int n,int m,int k)
{
    int top=min(n,k),ans=0;
    for(int i=0;i<=top;i++)    if(!((m-i)&1) && m>=i)
        upd(ans,1ll*C(n,i)*C(n-1+(m-i)/2,n-1)%mdn);
    return ans;
}
int main()
{
    int n=read(),m=read(); init(n+3*m);
    int ans=F(n,m*3,m)-1ll*(F(n,m,m)-F(n-1,m,m)+mdn)%mdn*n%mdn;
    printf("%d\n",(ans+mdn)%mdn);
    return 0;
}
AGC036C

Guess you like

Origin www.cnblogs.com/hanyuweining/p/11299284.html