Submission #545961

#TimeUsernameProblemLanguageResultExecution timeMemory
545961ivan_tudorMisspelling (JOI22_misspelling)C++14
0 / 100
1018 ms642692 KiB
#include <iostream> #include<bits/stdc++.h> using namespace std; const int N = 500005; const int MOD = 1e9 + 7; const int SIGMA = 26; void add(int &x, long long y){ y%=MOD; x += y; if(x >= MOD) x-=MOD; if(x<0) x+=MOD; } struct dphelper{ int nways; int lateless; int latebig; }; int lessthan[N]; int bigthan[N]; dphelper dp[N][SIGMA + 1][2][2]; const int INF = -1e9; int fbg[N], fls[N]; void compute(int n){ vector<int> st; st.push_back(n + 1); lessthan[n + 1] = n + 1; for(int i = n; i >=1; i--){ while(st.size() && lessthan[i] > lessthan[st.back()]) st.pop_back(); fls[i] = st.back(); st.push_back(i); } st.clear(); st.push_back(n + 1); bigthan[n + 1] = n + 1; for(int i = n; i >=1; i--){ while(st.size() && bigthan[i] > bigthan[st.back()]) st.pop_back(); fbg[i] = st.back(); st.push_back(i); } } int main() { int n, m; cin>>n>>m; for(int i = 1; i<=m; i++){ int x, y; cin>>x>>y; if(x < y) bigthan[x] = max(bigthan[x], y); if(x > y) lessthan[y] = max(lessthan[y], x);; } compute(n); for(int i = 0; i<=n; i++){ for(int let = 0; let<=SIGMA; let++){ for(int tp1 = 0; tp1<=1; tp1++) for(int tp2 = 0; tp2<=1; tp2++) dp[i][let][tp1][tp2] = {0, INF, INF}; } } for(int let = 1; let<=SIGMA; let++){ int ls = 0, bg = 0; if(lessthan[1]) ls = 1; if(bigthan[1]) bg = 1; if(ls == bg && ls == 1){ int lless, lbig; lless = lessthan[1]; lbig = bigthan[1]; int mn = min(lless, lbig); int futurels = 0, futurebg = 0; if(lless - mn> 0) futurels = 1; if(lbig - mn> 0) futurebg = 1; if(futurels == 0 && futurebg == 0) mn = min(mn, min(fls[1], fbg[1])); else if(futurels == 0) mn = min(mn, fls[1]); else mn = min(mn, fbg[1]); add(dp[mn][let][futurels][futurebg].nways, 1); /// o sa se pastreze restul restrictiilor if(futurels){ dp[mn][let][futurels][futurebg].lateless = max(dp[mn][let][futurels][futurebg].lateless, lless); } if(futurebg){ dp[mn][let][futurels][futurebg].latebig = max(dp[mn][let][futurels][futurebg].latebig, lbig); } } else{ dp[1][let][ls][bg].nways = 1; if(ls) dp[1][let][ls][bg].lateless = lessthan[1]; if(bg) dp[1][let][ls][bg].latebig = bigthan[1]; } } for(int i = 2; i<=n; i++){ /// propag pe i - 1, dupa pun restrictiile pt poz i noi si le scot pe cele vechi /// propag fara restrictii int total_sum = 0; for(int let = 1; let <= SIGMA; let++) add(total_sum, dp[i - 1][let][0][0].nways); for(int let = 1; let <= SIGMA; let++){ add(dp[i][let][0][0].nways, total_sum); } total_sum = 0; for(int let = SIGMA; let>= 1; let--){ add(dp[i][let][0][0].nways, total_sum); /// am pus mai mic si am scapat de restrictii add(total_sum, dp[i - 1][let][1][0].nways); if(dp[i - 1][let][1][0].lateless == i) add(dp[i][let][0][0].nways, dp[i - 1][let][1][0].nways); else{ add(dp[i][let][1][0].nways, dp[i -1][let][1][0].nways); dp[i][let][1][0].lateless = max(dp[i][let][1][0].lateless, dp[i -1][let][1][0].lateless); } } total_sum = 0; for(int let = 1; let<= SIGMA; let++){ add(dp[i][let][0][0].nways, total_sum); /// am pus mai mare si am scapat de restrictii add(total_sum, dp[i - 1][let][0][1].nways); if(dp[i - 1][let][0][1].latebig == i) add(dp[i][let][0][0].nways, dp[i - 1][let][0][1].nways); else{ add(dp[i][let][0][1].nways, dp[i -1][let][0][1].nways); dp[i][let][0][1].latebig = max(dp[i][let][0][1].latebig, dp[i -1][let][0][1].latebig); } } /// bag restrictiile noi for(int let = 1; let <=SIGMA; let++){ assert(dp[i][let][1][1].nways == 0); for(int ls = 1; ls >=0; ls--){ for(int bg = 1; bg >=0; bg--){ int newls = ls, newbg = bg; if(lessthan[i] > 0) newls = 1; if(bigthan[i] > 0) newbg = 1; if(newls == 1 && newbg == 1){ int lless, lbig; lless = dp[i][let][ls][bg].lateless; lbig = dp[i][let][ls][bg].latebig; lless = max(lless, lessthan[i]); lbig = max(lbig, bigthan[i]); if(dp[i][let][ls][bg].nways){ int mn = min(lless, lbig); int futurels = 0, futurebg = 0; if(lless - mn> 0) futurels = 1; if(lbig - mn> 0) futurebg = 1; if(futurels == 0 && futurebg == 0) mn = min(mn, min(fls[i], fbg[i])); else if(futurels == 0) mn = min(mn, fls[i]); else mn = min(mn, fbg[i]); add(dp[mn][let][futurels][futurebg].nways, dp[i][let][ls][bg].nways); /// o sa se pastreze restul restrictiilor if(futurels){ dp[mn][let][futurels][futurebg].lateless = max(dp[mn][let][futurels][futurebg].lateless, lless); } if(futurebg){ dp[mn][let][futurels][futurebg].latebig = max(dp[mn][let][futurels][futurebg].latebig, lbig); } } dp[i][let][ls][bg] = {0, INF, INF}; } else{ if(lessthan[i] > 0) dp[i][let][newls][newbg].lateless = max(dp[i][let][newls][newbg].lateless, lessthan[i]); if(bigthan[i] > 0) dp[i][let][newls][newbg].latebig = max(dp[i][let][newls][newbg].latebig, bigthan[i]); if((pair<int, int>){ls, bg} != (pair<int, int>){newls, newbg}){ /// cazul din 0 0 in cv ce nu e 1 0 sau 0 1 add(dp[i][let][newls][newbg].nways, dp[i][let][ls][bg].nways); dp[i][let][ls][bg] = {0, INF, INF}; } } } } } } int ans = 0; for(int let = 1; let<=SIGMA; let++){ add(ans, dp[n][let][0][0].nways); add(ans, dp[n][let][0][1].nways); add(ans, dp[n][let][1][0].nways); } cout<<ans; return 0; }
#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...