Submission #88811

#TimeUsernameProblemLanguageResultExecution timeMemory
88811jasony123123Rima (COCI17_rima)C++11
56 / 140
1088 ms110392 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; //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 *************************/ struct Dhash { ll x; Dhash() { x = 0; } Dhash(ll a) { x = a; } bool operator<(const Dhash other)const { return x < other.x; } Dhash operator+(const Dhash other)const { return Dhash(x + other.x); } Dhash operator*(const Dhash other)const { return Dhash(x * other.x); } Dhash operator*(const char other)const { return Dhash(x * (ll)other); } Dhash operator%(const Dhash other)const { return Dhash(x%other.x); } }; const int MAXL = 3000000; const int MAXN = 500000; struct HashTool { const Dhash MOD = Dhash(1000000009LL); const Dhash PRIME = Dhash(610639LL); static const int SZ = MAXL; Dhash p[SZ]; HashTool() { p[0] = 1; FOR(i, 1, SZ) p[i] = (p[i - 1] * PRIME) % MOD; } void calc(string &str, Dhash &full, Dhash &suff) { Dhash hsh = 0; RFORE(i, str.size() - 1, 0) { hsh = (hsh + ((p[str.size() - 1 - i] * str[i] ) % MOD)) % MOD; if (i == 1) suff = hsh; else if (i == 0) full = hsh; } } }; struct StringStuff { int len, gid; Dhash 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]; Dhash groupsuff[MAXN]; map<int, v<int>> allgroups; map<int, map<Dhash, int>> allstring; // all hash, group id v<int> roots; v<int> chil[MAXN]; int dfs(int x) { int ans = 0; for (int c : chil[x]) maxx(ans, dfs(c)); return ans + groupsz[x]; } //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[i].empty()) { // cout << "at length " << i << "\n"; // for (int g : allgroups[i]) // cout << "group " << g << "\n"; // } // if (!allstring[i].empty()) { // cout << "at length " << i << "\n"; // for (auto g : allstring[i]) // cout << "allhash " << g.first << " groupid " << g.second << "\n"; // } // } //} void genGroups() { map<pair<int, Dhash>, 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(); int ans = 0; for (int r : roots) maxx(ans, dfs(r)); cout << ans << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...