记录编号 384518 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI 2015]品酒大会 最终得分 100
用户昵称 GravatarRapiz 是否通过 通过
代码语言 C++ 运行时间 2.228 s
提交时间 2017-03-18 16:45:02 内存使用 99.30 MiB
显示代码纯文本
  1. #include <cstdio>
  2. #include <vector>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define file(x) "savour."#x
  6. const int N = 6e5 + 10;
  7. typedef long long ll;
  8. int n, last = 1, sz = 1, nxt[N][26], pre[N], val[N];
  9. char s[N];
  10. ll a[N], way[N], wei[N], ri[N], mx[N], mn[N], MX, MN;
  11. std::vector<int> to[N];
  12. inline void extend(int c) {
  13. int p = last, np = ++sz;
  14. val[np] = val[p] + 1;
  15. ri[np]++;
  16. for (;p&&!nxt[p][c]; p = pre[p]) nxt[p][c] = np;
  17. if (p) {
  18. int q = nxt[p][c];
  19. if (val[q] == val[p] + 1) pre[np] = q;
  20. else {
  21. int nq = ++sz;
  22. memcpy(nxt[nq], nxt[q], sizeof nxt[0]);
  23. val[nq] = val[p] + 1, pre[nq] = pre[q];
  24. pre[q] = nq, pre[np] = nq;
  25. for (;p&&nxt[p][c] == q; p = pre[p]) nxt[p][c] = nq;
  26. }
  27. }
  28. else pre[np] = 1;
  29. last = np;
  30. }
  31. int dfs(int p) {
  32. for (int i = 0; i < to[p].size(); i++) {
  33. int v = to[p][i];
  34. dfs(v);
  35. way[val[p]] += ri[p]*ri[v];
  36. if (mn[v] != MN) {
  37. if (mn[p] != MN) wei[val[p]] = std::max(wei[val[p]], mn[p]*mn[v]);
  38. mn[p] = std::min(mn[p], mn[v]);
  39. }
  40. if (mx[v] != MX) {
  41. if (mx[p] != MX) wei[val[p]] = std::max(wei[val[p]], mx[p]*mx[v]);
  42. mx[p] = std::max(mx[p], mx[v]);
  43. }
  44. ri[p] += ri[v];
  45. }
  46. return ri[p];
  47. }
  48. int main() {
  49. memset(mn,0x3f, sizeof mn);
  50. MN = mn[0];
  51. memset(mx, 0xc0, sizeof mx);
  52. memset(wei, 0xc0, sizeof(wei));
  53. MX = mx[0];
  54. freopen(file(in), "r", stdin);
  55. freopen(file(out), "w", stdout);
  56. scanf("%d%s", &n, s + 1);
  57. for (int i = 1; i <= n; i++) scanf("%lld", a + i);
  58. for (int i = n; i; i--) mx[sz + 1] = mn[sz + 1] = a[i], extend(s[i] - 'a');
  59. for (int i = 1; i <= sz; i++) to[pre[i]].push_back(i);
  60. dfs(1);
  61. for (int i = n - 1; i >= 0; i--) way[i] += way[i + 1], wei[i] = std::max(wei[i], wei[i + 1]);
  62. for (int i = 0; i < n; i++) printf("%lld %lld\n", way[i], wei[i] == wei[N - 1] ? 0 : wei[i]);
  63. }