Submission #88816

#TimeUsernameProblemLanguageResultExecution timeMemory
88816jasony123123Rima (COCI17_rima)C++11
56 / 140
1085 ms108260 KiB
#define _CRT_SECURE_NO_WARNINGS #include <bits/stdc++.h> #include <unordered_map> //#include <ext/pb_ds/tree_policy.hpp> //#include <ext/pb_ds/assoc_container.hpp> using namespace std; //using namespace __gnu_pbds; #define FOR(i,start,end) for(int i=start;i<(int)(end);i++) #define FORE(i,start,end) for(int i=start;i<=(int)end;i++) #define RFOR(i,start,end) for(int i = start; i>end; i--) #define RFORE(i,start,end) for(int i = start; i>=end; i--) #define all(a) a.begin(), a.end() #define mt make_tuple #define v vector #define sf scanf #define pf printf #define dvar(x) cout << #x << " := " << x << "\n" #define darr(x,n) FOR(i,0,n) cout << #x << "[" << i << "]" << " := " << x[i] << "\n" typedef long long ll; typedef long double ld; typedef pair<int, int > pii; typedef pair<ll, ll> pll; //template <class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; template<class T> void minn(T &a, T b) { a = min(a, b); } template<class T> void maxx(T &a, T b) { a = max(a, b); } void io() { #ifdef LOCAL_PROJECT freopen("input.in", "r", stdin); freopen("output.out", "w", stdout); #else /* online submission */ #endif ios_base::sync_with_stdio(false); cin.tie(NULL); } /**************************COCI 2016-2017 R4 P5 *************************/ const int MAXL = 3000000; const int MAXN = 500000; struct HashTool { const ll MOD = 1000000007LL; const ll PRIME = 105943LL; static const int SZ = MAXL; ll p[SZ]; HashTool() { p[0] = 1; FOR(i, 1, SZ) p[i] = (p[i - 1] * PRIME) % MOD; } void calc(string &str, ll &full, ll &suff) { ll hsh = 0; RFORE(i, str.size() - 1, 0) { hsh = (hsh + ((str[i] * p[str.size() - 1 - i]) % MOD)) % MOD; if (i == 1) suff = hsh; else if (i == 0) full = hsh; } } }; struct StringStuff { int len, gid; ll fullhsh, suffhsh; StringStuff(string &str, HashTool &h) { len = str.size(); h.calc(str, fullhsh, suffhsh); } }; int N; HashTool ht; v<StringStuff> vstring; int NG = 0; int groupsz[MAXN]; ll groupsuff[MAXN]; map<int, v<int>> allgroups; map<int, map<ll, int>> allstring; // all hash, group id v<int> roots; v<int> chil[MAXN]; int ans = 0; int dfs(int x) { // 1== root, 0 = not root pii bst = { 0, 0 }; for (int c : chil[x]) { int res = dfs(c); if (res > bst.second) swap(bst.second, res); if (bst.second > bst.first) swap(bst.second, bst.first); } maxx(ans, bst.first + bst.second + groupsz[x]); return groupsz[x] + bst.first; } void printGraph() { darr(roots, roots.size()); FOR(i, 0, NG) { cout << "group: " << i << "\n"; for (int c : chil[i]) cout << "child: " << c << "\n"; } } void buildGraph() { int maxlen = MAXL; RFORE(i, maxlen, 1) if (allgroups.find(i) != allgroups.end()) { for (int g : allgroups[i]) { if (allstring.find(i - 1) == allstring.end()) roots.push_back(g); else { auto it = allstring[i - 1].find(groupsuff[g]); if (it == allstring[i - 1].end()) roots.push_back(g); else chil[it->second].push_back(g); } } } } void printCheck() { dvar(N); FOR(i, 0, N) pf("string %d: len = %d gid = %d fullhsh = %lld suffhsh = %lld \n", i, vstring[i].len, vstring[i].gid, vstring[i].fullhsh, vstring[i].suffhsh); dvar(NG); darr(groupsz, NG); darr(groupsuff, NG); int maxlen = MAXL; RFORE(i, maxlen, 1) { if (allgroups.find(i) != allgroups.end()) { cout << "at length " << i << "\n"; for (int g : allgroups[i]) cout << "group " << g << "\n"; } if (allstring.find(i) != allstring.end()) { cout << "at length " << i << "\n"; for (auto g : allstring[i]) cout << "allhash " << g.first << " groupid " << g.second << "\n"; } } } void genGroups() { map<pair<int, ll>, v<int> > same; FOR(i, 0, N) same[{vstring[i].len, vstring[i].suffhsh}].push_back(i); for (auto &group : same) { groupsz[NG] = group.second.size(); groupsuff[NG] = group.first.second; allgroups[group.first.first].push_back(NG); for (auto &str : group.second) { vstring[str].gid = NG; allstring[group.first.first][vstring[str].fullhsh] = NG; } NG++; } } int main() { io(); cin >> N; FOR(i, 0, N) { string str; cin >> str; vstring.push_back(StringStuff(str, ht)); } genGroups(); // printCheck(); buildGraph(); // printGraph(); for (int r : roots) dfs(r); cout << ans << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...