Submission #574620

#TimeUsernameProblemLanguageResultExecution timeMemory
574620penguinhackerEnergetic turtle (IZhO11_turtle)C++14
100 / 100
243 ms12108 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define ar array const int mxN=3e5; int n, m, k, t, z, cnt[2*mxN+1]; ar<int, 2> cells[22]; vector<ar<int, 2>> pf; ll f[2*mxN+1], iF[2*mxN+1], ways[22][22], dp1[22], dp2[22][22]; vector<ar<int, 2>> ans_set; ll bp(ll b, int p, int M) { ll r=1; for (; p; p/=2, b=b*b%M) if (p%2) r=r*b%M; return r; } ll C(int a, int b, ar<int, 2> prime, int pp) { assert(0<=b&&b<=a&&a<=n+m); int pwr=cnt[a]-cnt[b]-cnt[a-b]; assert(pwr>=0); if (pwr>=prime[1]) return 0; ll r=f[a]*iF[b]%pp*iF[a-b]%pp; while(pwr--) r=r*prime[0]%pp; return r; } bool ord(int i, int j) { return cells[i][0]<=cells[j][0]&&cells[i][1]<=cells[j][1]; } void solve(ar<int, 2> prime) { int pp=1; for (int i=0; i<prime[1]; ++i) pp*=prime[0]; f[0]=1, iF[0]=1; for (int i=1; i<=n+m; ++i) { int x=i; cnt[i]=cnt[i-1]; while(x%prime[0]==0) x/=prime[0], ++cnt[i]; f[i]=f[i-1]*x%pp; iF[i]=bp(f[i], pp/prime[0]*(prime[0]-1)-1, pp); } auto Go=[&](int i, int j) { assert(ord(i, j)); int x=cells[j][0]-cells[i][0]; int y=cells[j][1]-cells[i][1]; return C(x+y, x, prime, pp); }; for (int i=0; i<k+2; ++i) for (int j=i+1; j<k+2; ++j) { assert(cells[i]!=cells[j]&&cells[i][0]<=cells[j][0]); if (!ord(i, j)) { ways[i][j]=0; continue; } ways[i][j]=Go(i, j); for (int a=i+1; a<j; ++a) { if (ord(i, a)&&ord(a, j)) { dp1[a]=Go(i, a); for (int b=i+1; b<a; ++b) if (ord(i, b)&&ord(b, a)) dp1[a]=(dp1[a]-dp1[b]*Go(b, a)%pp+pp)%pp; ways[i][j]=(ways[i][j]-dp1[a]*Go(a, j)%pp+pp)%pp; } } } memset(dp2, 0, sizeof(dp2)); dp2[0][0]=1; for (int i=1; i<k+2; ++i) for (int j=1; j<k+2; ++j) for (int a=0; a<i; ++a) if (ord(a, i)) dp2[i][j]=(dp2[i][j]+dp2[a][j-1]*ways[a][i])%pp; ll tot=0; for (int i=0; i<=t+1; ++i) tot=(tot+dp2[k+1][i])%pp; //cout << tot << " " << pp << endl; ans_set.push_back({(int)tot, pp}); } ar<int, 2> mrg(ar<int, 2> a, ar<int, 2> b) { assert(a[1]<b[1]); ar<int, 2> c={b[0], a[1]*b[1]}; for (int i=1; i<a[1]; ++i) { if (c[0]%a[1]==a[0]) break; c[0]+=b[1]; } assert(c[0]%a[1]==a[0]); return c; } int main() { ios::sync_with_stdio(0); cin.tie(0); cin >> n >> m >> k >> t >> z; // can hit <=t traps t=min(t, k); if (z==1) { cout << 0; return 0; } for (int i=2; i*i<=z; ++i) { if (z%i==0) { int c=0; while(z%i==0) z/=i, ++c; pf.push_back({i, c}); } } if (z>1) pf.push_back({z, 1}); for (int i=0; i<k; ++i) cin >> cells[i][0] >> cells[i][1]; cells[k+1]={n, m}; sort(cells, cells+k+2); for (ar<int, 2> prime : pf) solve(prime); sort(ans_set.begin(), ans_set.end(), [&](ar<int, 2> a, ar<int, 2> b) { return a[1]<b[1]; }); while(ans_set.size()>1) { ar<int, 2> b=ans_set.back(); ans_set.pop_back(); ar<int, 2> a=ans_set.back(); ans_set.pop_back(); ans_set.push_back(mrg(a, b)); } cout << ans_set[0][0]; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...