Submission #145174

#TimeUsernameProblemLanguageResultExecution timeMemory
145174darkkcyanRima (COCI17_rima)C++14
140 / 140
765 ms47416 KiB
#include <bits/stdc++.h> using namespace std; using namespace std::placeholders; #define llong long long #define xx first #define yy second #define len(x) ((int)x.size()) #define rep(i,n) for (int i = -1; ++ i < n; ) #define rep1(i,n) for (int i = 0; i ++ < n; ) #define all(x) x.begin(), x.end() // #define rand __rand // mt19937 rng(chrono::system_clock::now().time_since_epoch().count()); // or mt19937_64 // template<class T = int> T rand(T range = numeric_limits<T>::max()) { // return (T)(rng() % range); // } #define rem ((llong) 1000027241) #define base 31 #define maxn 501010 int dsu[maxn]; int set_cnt[maxn]; int find_set(int u) { return u == dsu[u] ? u : dsu[u] = find_set(dsu[u]); } void join(int u, int v) { if (rand() & 1) swap(u, v); u = find_set(u); v = find_set(v); if (u == v) return ; set_cnt[u] += set_cnt[v]; dsu[v] = u; } struct word { llong hash_code; int length; word(llong hc = 0, int l = 0): hash_code(hc), length(l) {} word(const string& s, int l = -1): hash_code(0), length(l) { if (length == -1) length = len(s); rep(i, length) ((hash_code *= base) += s[i] - 'a' + 1) %= rem; } word add(char ch) { return word((hash_code * base + ch - 'a' + 1) % rem, length + 1); } }; bool operator< (const word& u, const word& v) { if (u.length == v.length) return u.hash_code < v.hash_code; return u.length < v.length; } int n; word words[maxn], pref_words[maxn]; bool has_parent[maxn]; vector<int> gr[maxn]; pair<int, int> dfs(int u, int p = -1) { bool can_go_to_parent = set_cnt[u] > 1 and p != -1; pair<int, int> ans(set_cnt[u] + can_go_to_parent, set_cnt[u]); for (auto v: gr[u]) { if (v == p) continue; auto temp = dfs(v, u); ans.xx = max(ans.xx, temp.xx); ans.xx = max(ans.xx, temp.yy + ans.yy + can_go_to_parent); ans.yy = max(ans.yy, set_cnt[u] + temp.yy); } return ans; } int main(void) { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; rep(i, n) { string s; cin >> s; reverse(s.begin(), s.end()); pref_words[i] = word(s, len(s) - 1); words[i] = pref_words[i].add(s.back()); } rep(i, n) { dsu[i] = i; set_cnt[i] = 1; } map<word, int> pref_pos; rep(i, n) { if (!pref_pos.count(pref_words[i])) pref_pos[pref_words[i]] = i; else join(i, pref_pos[pref_words[i]]); } rep(i, n) { if (!pref_pos.count(words[i])) continue; int u = find_set(i); int v = find_set(pref_pos[words[i]]); gr[u].emplace_back(v); has_parent[v] = 1; } int ans = 0; rep(i, n) { if (i != find_set(i)) continue; if (has_parent[i]) continue; ans = max(ans, dfs(i).xx); } cout << ans; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...