Submission #1219954

#TimeUsernameProblemLanguageResultExecution timeMemory
1219954tosivanmakFestivals in JOI Kingdom 2 (JOI23_festival2)C++20
87 / 100
1022 ms424036 KiB
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll MOD;
ll bm(ll a, ll b){
    if(b==0)return 1;
    ll k=bm(a,b/2);
    k*=k; k%=MOD;
    if(b&1)k*=a;
    k%=MOD; return k;
}
ll inv(ll a){
    return bm(a,MOD-2);
}
int dp[6005][3005][2][2];
ll fact[6005],ifact[6005];
ll tot[6005][3005];
/*
    Dimensions:
    1. The position
    2. Number of open brackets
    3. Whether or not the worse strategy has a corresponding open bracket
    4. Delta (better strategy - worse strategy)
*/
void add(int& a, int& b){
    a+=b; a%=MOD;
    // cout<<a<<'\n';
}
int P(int a, int b){
    ll aa=a; ll bb=b;
    ll k=fact[aa]*ifact[aa-bb]%MOD;
    int kk=k;
    return kk;
}
ll C(ll n, ll r){
    return fact[n]*ifact[r]%MOD*ifact[n-r]%MOD;
}
int comb(int a, int b, int c){
    // P(b,c)*a
    int sz=P(b,c);
    // cout<<"P val "<<P(0,0)<<'\n';
    ll ssz=sz; ssz*=a; ssz%=MOD;
    sz=ssz;
    return sz;
}
int mul(ll a, int b){
    a*=b; a%=MOD; a+=MOD; a%=MOD;
    int val=a; return val;
}
string pr(int a, int b, int c, int d){
    string st="dp["+to_string(a)+"]"+"["+to_string(b)+"]"+"["+to_string(c)+"]"+"["+to_string(d)+"]=";
    return st;
}
void solve(){
    ll n;
    cin>>n>>MOD;
    fact[0]=1;
    ifact[0]=1;
    for(int i=1;i<=6000;i++){
        fact[i]=fact[i-1]*i; fact[i]%=MOD;
        ifact[i]=inv(fact[i]);
    }
    dp[0][0][0][0]=1;
    for(int i=0;i<2*n;i++){
        for(int j=0;j<=n;j++){
           //1. Delta = 1, no corresponding bracket, open bracket for next
        //    add(dp[i+1][j+1][1][1],dp[i][j][0][1]);
           //2. Delta = 1, no corresponding bracket, close bracket for next, Impossible
           //3. Delta = 1, have corresponding bracket, open bracket for next
           add(dp[i+1][j+1][1][1],dp[i][j][1][1]);
           //4. Delta = 1, have corresponding bracket, close bracket for next
           if(j!=0)add(dp[i+1][j-1][0][0],dp[i][j][1][1]);
           //5. Delta = 0, no corresponding bracket, open bracket for next
           add(dp[i+1][j+1][1][0],dp[i][j][0][0]);
           //6. Delta = 0, no corresponding bracket, close bracket for next
        //    if(j!=0)add(dp[i+1][j-1][0][1],dp[i][j][0][0]); // Need speed up
           if(i+j<=2*n&&j!=0){
               ll val=comb(dp[i][j][0][0],2*n-(i+1),j-1);
               int rb=mul(val,j);
               add(dp[i+j][0][0][1],rb);
           }
           //7. Delta = 0, have corresponding bracket, open bracket for next
           add(dp[i+1][j+1][1][0],dp[i][j][1][0]);
           //8. Delta = 0, have corresponding bracket, close bracket for next
           // Case 1: Close for both worse and better
        //    if(j!=0)add(dp[i+1][j-1][0][0],dp[i][j][1][0]); // Need speed up
            if(i+j<=2*n&&j!=0){
               int val=comb(dp[i][j][1][0],2*n-(i+1),j-1);
            //    cout<<i<<" "<<j<<" "<<1<<' '<<0<<" "<<2*n-(i+1)<<" "<<j-1<<' '<<val<<'\n';
               add(dp[i+j][0][0][0],val);
           }
           // Case 2: Close for only the better
        //    if(j!=0)add(dp[i+1][j-1][1][1],dp[i][j][1][0]); // Need speed up
           if(i+j-1<=2*n&&j>1){
               ll val=comb(dp[i][j][1][0],2*n-(i+1),j-2);
               int rb=mul(val,j-1);
               add(dp[i+j-1][1][1][1],rb);
           }
        }
    }
    // for(int i=1;i<=2*n;i++){
    //     for(int j=0;j<=n;j++){
    //         cout<<pr(i,j,0,0)<<dp[i][j][0][0]<<" "<<pr(i,j,0,1)<<dp[i][j][0][1]<<' '<<pr(i,j,1,0)<<dp[i][j][1][0]<<' '<<pr(i,j,1,1)<<dp[i][j][1][1]<<'\n';
    //     }
    //     cout<<'\n';
    // }
    // dp[2][0][0][0]=1, dp[2][2][1][0]=1
    // dp[3][1][1][0]=1, dp[3][1][1][1]=1, dp[3][3][1][0]=1, 
    for(int i=0;i<2*n+5;i++){
        for(int j=0;j<n+5;j++)tot[i][j]=0;
    }
    tot[0][0]=1;
    for(int i=1;i<=2*n;i++){
        for(int j=0;j<=n;j++){
            if(j!=0)tot[i][j]=tot[i-1][j-1];
            tot[i][j]+=(tot[i-1][j+1]*(j+1)%MOD); tot[i][j]%=MOD;
        }
    }
    ll totals=tot[2*n][0];
    totals-=(dp[2*n][0][0][0]+dp[2*n][0][1][0]);
    totals%=MOD; totals+=MOD; totals%=MOD;
    cout<<totals<<'\n';
}
int32_t main(){
    // freopen("debug.txt","w",stdout);
    ll t=1;
    // cin>>t;
    while(t--)solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...