Submission #58379

#TimeUsernameProblemLanguageResultExecution timeMemory
58379BenqEnergetic turtle (IZhO11_turtle)C++14
100 / 100
970 ms75640 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/tree_policy.hpp> #include <ext/pb_ds/assoc_container.hpp> using namespace std; using namespace __gnu_pbds; typedef long long ll; typedef long double ld; typedef complex<ld> cd; typedef pair<int, int> pi; typedef pair<ll,ll> pl; typedef pair<ld,ld> pd; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; typedef vector<pi> vpi; typedef vector<pl> vpl; typedef vector<cd> vcd; template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>; #define FOR(i, a, b) for (int i=a; i<(b); i++) #define F0R(i, a) for (int i=0; i<(a); i++) #define FORd(i,a,b) for (int i = (b)-1; i >= a; i--) #define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--) #define sz(x) (int)(x).size() #define mp make_pair #define pb push_back #define f first #define s second #define lb lower_bound #define ub upper_bound #define all(x) x.begin(), x.end() const int MOD = 1000000007; const ll INF = 1e18; const int MX = 100001; namespace NT { vpi fac(int x) { vpi pri; for (int i = 2; i*i <= x; ++i) if (x % i == 0) { int t = 0; while (x % i == 0) x /= i, t ++; pri.pb({i,t}); } if (x > 1) pri.pb({x,1}); return pri; } int phi(int x) { for (auto a: fac(x)) x /= a.f, x *= a.f-1; return x; } ll inv(ll a, ll b) { // 0 < a < b, gcd(a,b) = 1 a %= b; if (a <= 1) return a; ll i = inv(b%a,a); ll tmp = -((b/a)*i+((b%a)*i)/a) % b; if (tmp < 0) tmp += b; return tmp; } pl CRT(pl a, pl b) { // Chinese Remainder Theorem, Verified by Kattis generalchineseremainder ll g = __gcd(a.s,b.s), l = a.s*b.s/g; if ((b.f-a.f) % g != 0) return {-1,-1}; ll A = a.s/g, B = b.s/g; ll mul = (b.f-a.f)/g*inv(A%B,B) % B; return {((mul*a.s+a.f)%l+l)%l,l}; } }; template<int SZ> struct ComboPower { pl fac[SZ+1], ifac[SZ+1], mod; ll MOD = 1; void init(pl _mod) { // prime, power mod = _mod; F0R(i,mod.s) MOD *= mod.f; fac[0] = ifac[0] = {1,0}; FOR(i,1,SZ+1) { fac[i] = fac[i-1]; int I = i, z = 0; while (I % mod.f == 0) I /= mod.f, z++; fac[i].f = fac[i].f*I%MOD; fac[i].s += z; ifac[i] = {NT::inv(fac[i].f,MOD),fac[i].s}; } } ll comb(ll a, ll b) { if (a < b || b < 0) return 0; ll tmp = (fac[a].f*ifac[b].f%MOD)*ifac[a-b].f % MOD; ll z = fac[a].s-fac[b].s-fac[a-b].s; if (z >= mod.s) return 0; F0R(i,z) tmp = tmp*mod.f % MOD; return tmp; } }; template<int SZ> struct ComboGeneral { vector<ComboPower<SZ>> v; ll MOD; void init(ll _MOD) { MOD = _MOD; for (auto a: NT::fac(MOD)) { v.pb(ComboPower<SZ>()); v.back().init(a); } } ll comb(ll a, ll b) { pl cur = {0,1}; for (auto& x: v) cur = NT::CRT({x.comb(a,b),x.MOD},cur); return cur.f; } }; ComboGeneral<600001> C; int get(pi a, pi b) { return C.comb(b.f-a.f+b.s-a.s,b.s-a.s); } int N,M,K,T,Z, ways[22][22], dp[22][22]; vpi p; ll ad(ll a, ll b) { return (a+b)%Z; } ll sub(ll a, ll b) { return (a-b+Z)%Z; } ll mul(ll a, ll b) { return a*b%Z; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> M >> K >> T >> Z; C.init(Z); F0R(i,K) { int X,Y; cin >> X >> Y; p.pb({X,Y}); } p.pb({0,0}); sort(all(p)); p.pb({N,M}); F0R(i,sz(p)) F0Rd(j,i) { ways[j][i] = get(p[j],p[i]); FOR(k,j+1,i) ways[j][i] = sub(ways[j][i],mul(ways[j][k],get(p[k],p[i]))); // cout << j << " " << i << " " << ways[j][i] << "\n"; } dp[0][0] = 1; FOR(i,1,sz(p)) F0R(j,i) FOR(k,1,T+2) dp[i][k] = ad(dp[i][k],mul(dp[j][k-1],ways[j][i])); int ans = 0; FOR(i,1,T+2) ans = ad(ans,dp[sz(p)-1][i]); cout << ans; } /* Look for: * the exact constraints (multiple sets are too slow for n=10^6 :( ) * special cases (n=1?) * overflow (ll vs int?) * array bounds */
#Verdict Execution timeMemoryGrader output
Fetching results...