Submission #1275356

#TimeUsernameProblemLanguageResultExecution timeMemory
1275356cngkhanh_ti22Linear Garden (IOI08_linear_garden)C++20
100 / 100
195 ms9432 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define fi first #define se second #define dp(a, b, c, d) dpa[a][b + 2][c + 2][d] template<class T, class P> bool maximize(T &a, P b){ if(a < b) return a = b, true; return false;} template<class T, class P> bool minimize(T &a, P b){ if(a > b) return a = b, true; return false;} int n, m; string s; int dpa[2][5][4][3], res; //using array => 70% score (MLE on codeforces, depending on the oj, some only counts used array elements) //using vector => 60% score /* vector<vector<vector<vector<int>>>> dpa; dpa = vector<vector<vector<vector<int>>>>(n + 1, vector<vector<vector<int>>>(5, vector<vector<int>>(5, vector<int>(5, 0)))); */ //L = +1, P = -1 //dp[len][sum][sumMin][sumMax] = the number of ways to create <sum> from a string with length <len>... //IMPROVEMENT: dp[id]... = the number of ways to create <sum> from a string with length <curN> //... with <sumMin> and <sumMax> being the min and max of sum on the way of creating <len> from <len - 1> struct state{ int len, sum, nn, ln; }; deque<state> skipped; void findSkipped(){ int prefix = 0; int opt; int nn = 0, ln = 0; for(int i = 0; i < n; i++){ opt = prefix - nn + 1; //try to maximize 'L', opt <= 2 meaning 'L' can be used here if(opt <= 2 && s[i] != 'L'){ //if not optimised, calculate the number of string skipped opt += nn; //opt = prefix with 'L' being added skipped.push_front({n - i - 1, opt, nn, ln}); } if(s[i] == 'L') prefix++; else prefix--; maximize(ln, prefix); minimize(nn, prefix); } } int curN = 0, id = 0; void calcDp(){ curN++; id ^= 1; memset(dpa[id], 0, sizeof(dpa[id])); //adding an L for(int s = -1; s <= 2; s++){ for(int k = max(-2, s - 2); k <= 1; k++){ for(int j = 0; j <= 2; j++){ (dp(id, s, min(k, s - 1), max(j, s - 1)) += dp(id ^ 1, s - 1, k, j)) %= m; } } } //adding a P for(int s = -2; s <= 1; s++){ for(int k = 0; k <= min(2, s + 2); k++){ for(int j = -2; j <= k; j++){ (dp(id, s, min(j, s + 1), max(k, s + 1)) += dp(id ^ 1, s + 1, j, k)) %= m; } } } } void solve(){ int len, opt, nn, ln; while(skipped.size()){ len = skipped.front().len; opt = skipped.front().sum; nn = skipped.front().nn; ln = skipped.front().ln; while(curN < len) calcDp(); //opt - nn + j - k <= 2 => k >= opt - nn + j - 2 //opt - ln + j - l >= -2 => l <= opt - ln + j + 2 for(int j = -2; j <= 2; j++){//sum for(int k = max(-2, opt - nn + j - 2); k <= 1; k++){//min for(int l = max(-1, k); l <= min(2, opt - ln + j + 2); l++){//max (res += dp(id, j, k, l)) %= m; } } } skipped.pop_front(); } } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); if(fopen("main.inp", "r")){ freopen("main.inp", "r", stdin); freopen("main.out", "w", stdout); } cin >> n >> m; cin >> s; dp(0, 0, 0, 0) = 1; findSkipped(); solve(); cout << (++res) % m; return 0; }

Compilation message (stderr)

linear_garden.cpp: In function 'int main()':
linear_garden.cpp:105:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  105 |         freopen("main.inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
linear_garden.cpp:106:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  106 |         freopen("main.out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#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...
#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...
#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...