Submission #316585

# Submission time Handle Problem Language Result Execution time Memory
316585 2020-10-26T18:21:33 Z ehab_fawzy Energetic turtle (IZhO11_turtle) C++14
100 / 100
931 ms 6136 KB
//#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define F first
#define S second
#define pb push_back
#define ll long long
#define all(x) x.begin() , x.end()
#define rep(i,s,e) for (int i = s; i < e; ++i)
#define rev(i,s,e) for (int i = s; i > e; --i)
#define mem(a,v) memset(a , v , sizeof a)
#define negmod(x,m) ((x%m + m)%m)
template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
        tree_order_statistics_node_update>;

const int N = 25 , M = 7e5 + 9;

ll n , m , k , t, mod , paths[N][N];
vector<pair<ll,ll>> points;

ll add( ll x , ll y ){
    ll ret = x + y;
    while ( ret >= mod ) ret -= mod;
    while ( ret <  0   ) ret += mod;
    return ret;
}
ll mul( ll x , ll y ){
    ll ret = x * y;
    if ( ret >= mod ) ret %= mod;
    if ( ret <  0   ) ret  = negmod(ret , mod);
    return ret;
}

inline ll pwr( ll x , ll y ){
    if ( y == 0 ) return mul(1 , 1);
    if ( y == 1 ) return mul(x , 1);
    return mul( (y&1 ? x : 1) , pwr( mul(x,x) , y >> 1 ) );
}

int pr[M] , comp[M] , ptr;
void linear_sieve() {
    for (int i = 2; i < M; ++i) {
        if (!comp[i]) pr[ptr++] = i , comp[i] = i;
        rep(j, 0, ptr) {
            ll mul = 1LL * i * pr[j];
            if (mul > M) break;
            comp[mul] = pr[j];
            if (i % pr[j] == 0) break;
        }
    }
}

int factorsCnt[M] , lst[M] , itr;
ll pCr( ll P , ll R ){
    if ( P < R ) return 0;
    if ( P < 0 or R < 0 ) return 0;
    itr = 0; ll df = P - R , cur;
    for ( int i = P; i > 1; --i ){
        cur = i;
        while ( cur > 1 ){
            if ( factorsCnt[comp[cur]]++ == 0 )
                lst[itr++] = comp[cur];
            cur /= comp[cur];
        }
    }
    int scale ;
    for ( int i = max(R , df); i > 1; --i ){
        scale = (i <= R) + (i <= df); cur = i;
        while ( cur > 1 ){
            factorsCnt[comp[cur]] -= scale;
            cur /= comp[cur];
        }
    }

    ll ans = 1;
    while ( ~--itr ){
        if ( factorsCnt[lst[itr]] > 0 ){
            ans = mul(ans , pwr(lst[itr] , factorsCnt[lst[itr]])) ;
        }
        factorsCnt[lst[itr]] = 0;
    }
    return ans ;
}

ll pathsCnt( int i , int j ){
    ll X = points[j].F - points[i].F + 1;
    ll Y = points[j].S - points[i].S + 1;
    ll P = X + Y - 2 , R = X - 1;
    return pCr(P , R);
}

ll dp[N][N][N];

int main() {
//    freopen("turtle.in"  , "r" , stdin );
//    freopen("turtle.out" , "w" , stdout);
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#ifdef CLion
    freopen("input.txt" , "r" , stdin);
//    freopen("output.txt", "w" , stdout);
#endif

    linear_sieve();
    cin >> n >> m >> k >> t >> mod;
    rep(i,0,k){
        int x , y;
        cin >> x >> y;
        points.pb({x , y});
    }
    points.pb({0 , 0});
    points.pb({n , m});
    sort( all(points) );
    k = points.size();

    for ( int i = 0; i < k; ++i ){
        for ( int j = i + 1; j < k; ++j ){
            paths[i][j] = pathsCnt(i , j);
        }
    }

    for ( int i = 0; i < k; ++i ){
        for ( int j = i + 1; j < k; ++j ){
            dp[i][j][0] = paths[i][j];
            for ( int p = i + 1; p < j; ++p ){
                if ( points[p].S >= points[i].S and points[p].S <= points[j].S ){
                    dp[i][j][0] = add( dp[i][j][0] , -mul(dp[i][p][0] , paths[p][j]) );
                }
            }
        }
    }

    ll ans = dp[0][k - 1][0];
    for ( int steps = 1; steps <= t; ++steps ){
        for ( int i = 0; i < k; ++i ){
            for ( int j = i + 1; j < k; ++j ){
                for ( int p = i + 1; p < j; ++p ){
                    if ( points[p].S >= points[i].S and points[p].S <= points[j].S ){
                        dp[i][j][steps] = add( dp[i][j][steps] , mul(dp[i][p][0] , dp[p][j][steps - 1]) );
                    }
                }
            }
        }
        ans = add(ans , dp[0][k - 1][steps] );
    }

    cout << ans ;
    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 8 ms 3328 KB Output is correct
2 Correct 8 ms 3328 KB Output is correct
3 Correct 8 ms 3328 KB Output is correct
4 Correct 8 ms 3456 KB Output is correct
5 Correct 9 ms 3456 KB Output is correct
6 Correct 9 ms 3456 KB Output is correct
7 Correct 10 ms 3456 KB Output is correct
8 Correct 10 ms 3328 KB Output is correct
9 Correct 26 ms 3448 KB Output is correct
10 Correct 44 ms 3456 KB Output is correct
11 Correct 262 ms 4216 KB Output is correct
12 Correct 785 ms 6008 KB Output is correct
13 Correct 380 ms 5496 KB Output is correct
14 Correct 319 ms 4220 KB Output is correct
15 Correct 369 ms 4216 KB Output is correct
16 Correct 767 ms 5880 KB Output is correct
17 Correct 690 ms 5880 KB Output is correct
18 Correct 931 ms 6136 KB Output is correct
19 Correct 867 ms 6136 KB Output is correct
20 Correct 770 ms 6136 KB Output is correct