Advertisement
Guest User

Untitled

a guest
Jan 11th, 2016
1,596
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.06 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define forn(i, n) for (int i = 0; i < int(n); i++)
  4. #define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
  5. #define fore(i, l, r) for (int i = int(l); i < int(r); i++)
  6. #define correct(x, y, n, m) (0 <= (x) && (x) < (n) && 0 <= (y) && (y) < (m))
  7. #define all(a) (a).begin(), (a).end()
  8. #define sz(a) int((a).size())
  9. #define pb(a) push_back(a)
  10. #define mp(x, y) make_pair((x), (y))
  11. #define x first
  12. #define y second
  13.  
  14. using namespace std;
  15.  
  16. typedef long long li;
  17. typedef long double ld;
  18. typedef pair<int, int> pt;
  19.  
  20. template<typename X> inline X abs(const X& a) { return a < 0? -a: a; }
  21. template<typename X> inline X sqr(const X& a) { return a * a; }
  22.  
  23. const int INF = int(1e9);
  24. const li INF64 = li(1e18);
  25. const ld EPS = 1e-9, PI = 3.1415926535897932384626433832795;
  26.  
  27. const int NN = 100100, L = 500100;
  28.  
  29. int k;
  30. char buf[L];
  31. string a[NN];
  32. int c[NN];
  33.  
  34. inline bool read() {
  35.     if (!(cin >> k)) return false;
  36.     forn(i, k) {
  37.         assert(scanf("%s", buf) == 1);
  38.         a[i] = string(buf);
  39.     }
  40.     forn(i, k) assert(scanf("%d", &c[i]) == 1);
  41.     return true;
  42. }
  43.  
  44. struct node {
  45.     int l, r;
  46.     int parent, link;
  47.     map<int, int> next;
  48.     node(int l = 0, int r = 0, int parent = 0): l(l), r(r), parent(parent) {
  49.         link = -1;
  50.         next.clear();
  51.     }
  52. };
  53. struct state {
  54.     int v, pos;
  55.     state(int v = 0, int pos = 0): v(v), pos(pos) { }
  56. };
  57. const int N = 1000 * 1000 + 3;
  58. int n;
  59. int s[N];
  60. int tsz = 1;
  61. node t[2 * N];
  62. state ptr;
  63. inline int len(int v) { return t[v].r - t[v].l; }
  64. inline int split(state st) {
  65.     if (st.pos == 0) return t[st.v].parent;
  66.     if (st.pos == len(st.v)) return st.v;
  67.     int cur = tsz++;
  68.     t[cur] = node(t[st.v].l, t[st.v].l + st.pos, t[st.v].parent);
  69.     t[cur].next[s[t[st.v].l + st.pos]] = st.v;
  70.     t[t[st.v].parent].next[s[t[st.v].l]] = cur;
  71.     t[st.v].parent = cur;
  72.     t[st.v].l += st.pos;
  73.     return cur;
  74. }
  75. state go(state st, int l, int r) {
  76.     while (l < r) {
  77.         if (st.pos == len(st.v)) {
  78.             if (!t[st.v].next.count(s[l])) return state(-1, -1);
  79.             st = state(t[st.v].next[s[l]], 0);
  80.         }
  81.         else {
  82.             if (s[t[st.v].l + st.pos] != s[l]) return state(-1, -1);
  83.             int d = min(len(st.v) - st.pos, r - l);
  84.             l += d;
  85.             st.pos += d;
  86.         }
  87.     }
  88.     return st;
  89. }
  90. int link(int v) {
  91.     int& ans = t[v].link;
  92.     if (ans != -1) return ans;
  93.     if (v == 0) return ans = 0;
  94.     int p = t[v].parent;
  95.     return ans = split(go(state(link(p), len(link(p))), t[v].l + (p == 0), t[v].r));
  96. }
  97. inline void treeExtand(int i) {
  98.     while (true) {
  99.         state next = go(ptr, i, i + 1);
  100.         if (next.v != -1) {
  101.             ptr = next;
  102.             break;
  103.         }
  104.         int mid = split(ptr), cur = tsz++;
  105.         t[cur] = node(i, n, mid);
  106.         t[mid].next[s[i]] = cur;
  107.         if (mid == 0) break;
  108.         ptr = state(link(mid), len(link(mid)));
  109.     }
  110. }
  111.  
  112. li ans;
  113. set<pt> pos;
  114.  
  115. li dfs(int v, int len) {
  116.     //if (v) assert(t[v].l < t[v].r);
  117.     li sum = 0;
  118.     auto it = pos.lower_bound(mp(t[v].l, -INF));
  119.     if (it != pos.end() && it->x < t[v].r) {
  120.         //cerr << "len=" << len << " l=" << t[v].l << " r=" << t[v].r << endl;
  121.         sum += it->y;
  122.         if (it->x > t[v].l) {
  123.             len += it->x - t[v].l;
  124.             ans = max(ans, len * sum);
  125.         }
  126.         return sum;
  127.     }
  128.  
  129.     len += t[v].r - t[v].l;
  130.     for (auto nt : t[v].next)
  131.         sum += dfs(nt.y, len);
  132.     ans = max(ans, len * sum);
  133.     return sum;
  134. }
  135.  
  136. inline ostream& operator<< (ostream& out, const pt& p) { return out << "(" << p.x << ", " << p.y << ")"; }
  137.  
  138. inline void solve() {
  139.     n = 0;
  140.     pos.clear();
  141.     forn(i, k) {
  142.         forn(j, sz(a[i])) s[n++] = int(a[i][j]);
  143.         pos.insert(mp(n, c[i]));
  144.         s[n++] = 300 + i;
  145.     }
  146.  
  147.     //for (auto it : pos) cerr << it << ' '; cerr << endl;
  148.  
  149.     //cerr << n << endl;
  150.     //forn(i, n) cerr << s[i] << ' '; cerr << endl;
  151.    
  152.     forn(i, tsz) t[i] = node();
  153.     ptr = state();
  154.     tsz = 1;
  155.     forn(i, n) treeExtand(i);
  156.  
  157.     ans = 0;
  158.     dfs(0, 0);
  159.     cout << ans << endl;
  160.  
  161.     /*li s = 0;
  162.     forn(i, k) s += c[i];
  163.     cerr << s << endl;*/
  164. }
  165.  
  166. int main() {
  167. #ifdef SU1
  168.     assert(freopen("input.txt", "rt", stdin));
  169.     //assert(freopen("output.txt", "wt", stdout));
  170. #endif
  171.    
  172.     cout << setprecision(10) << fixed;
  173.     cerr << setprecision(5) << fixed;
  174.  
  175.     while (read()) {
  176.         solve();
  177.         //break;
  178.     }
  179.    
  180.     return 0;
  181. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement