题面

Bzoj4199

Sol

后缀数组

显然的暴力就是求\(LCP\)+差分

\(40\)分

  1. # include <bits/stdc++.h>
  2. # define RG register
  3. # define IL inline
  4. # define Fill(a, b) memset(a, b, sizeof(a))
  5. using namespace std;
  6. typedef long long ll;
  7. const int _(3e5 + 5);
  8. IL int Input(){
  9. RG int x = 0, z = 1; RG char c = getchar();
  10. for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
  11. for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
  12. return x * z;
  13. }
  14. int a[_], n, s[_], rk[_], sa[_], height[_], tmp[_], t[_];
  15. ll ans1[_], ans2[_];
  16. int st[20][_], lg[_];
  17. char ss[_];
  18. IL int Cmp(RG int i, RG int j, RG int k){
  19. return tmp[i] == tmp[j] && i + k <= n && j + k <= n && tmp[i + k] == tmp[j + k];
  20. }
  21. IL void Suffix_Sort(){
  22. RG int m = 26;
  23. for(RG int i = 1; i <= n; ++i) ++t[rk[i] = s[i]];
  24. for(RG int i = 1; i <= m; ++i) t[i] += t[i - 1];
  25. for(RG int i = n; i; --i) sa[t[rk[i]]--] = i;
  26. for(RG int k = 1; k <= n; k <<= 1){
  27. RG int l = 0;
  28. for(RG int i = n - k + 1; i <= n; ++i) tmp[++l] = i;
  29. for(RG int i = 1; i <= n; ++i) if(sa[i] > k) tmp[++l] = sa[i] - k;
  30. for(RG int i = 0; i <= m; ++i) t[i] = 0;
  31. for(RG int i = 1; i <= n; ++i) ++t[rk[tmp[i]]];
  32. for(RG int i = 1; i <= m; ++i) t[i] += t[i - 1];
  33. for(RG int i = n; i; --i) sa[t[rk[tmp[i]]]--] = tmp[i];
  34. swap(tmp, rk), rk[sa[1]] = l = 1;
  35. for(RG int i = 2; i <= n; ++i) rk[sa[i]] = Cmp(sa[i - 1], sa[i], k) ? l : ++l;
  36. if(l >= n) break;
  37. m = l;
  38. }
  39. for(RG int i = 1, h = 0; i <= n; ++i){
  40. if(h) --h;
  41. while(s[i + h] == s[sa[rk[i] - 1] + h]) ++h;
  42. height[rk[i]] = h;
  43. }
  44. }
  45. IL void ST_Prepare(){
  46. for(RG int i = 2; i <= n; ++i) lg[i] = lg[i >> 1] + 1;
  47. for(RG int i = 1; i <= n; ++i) st[0][i] = height[i];
  48. for(RG int i = 1; i <= lg[n]; ++i)
  49. for(RG int j = 1; j + (1 << i) - 1 <= n; ++j)
  50. st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
  51. }
  52. IL int LCP(RG int x, RG int y){
  53. x = rk[x], y = rk[y];
  54. if(x > y) swap(x, y); ++x;
  55. RG int len = y - x + 1;
  56. return min(st[lg[len]][x], st[lg[len]][y - (1 << lg[len]) + 1]);
  57. }
  58. int main(RG int argc, RG char* argv[]){
  59. Fill(ans2, -127), n = Input(), scanf(" %s", ss + 1);
  60. for(RG int i = 1; i <= n; ++i) s[i] = ss[i] - 'a' + 1, a[i] = Input();
  61. Suffix_Sort(), ST_Prepare();
  62. for(RG int i = 1; i < n; ++i)
  63. for(RG int j = i + 1; j <= n; ++j){
  64. RG int lcp = LCP(i, j);
  65. ++ans1[0], --ans1[lcp + 1];
  66. ans2[lcp] = max(ans2[lcp], 1LL * a[i] * a[j]);
  67. }
  68. for(RG int i = 0; i < n; ++i) ans1[i] += ans1[i - 1];
  69. for(RG int i = n - 1; ~i; --i) ans2[i] = max(ans2[i], ans2[i + 1]);
  70. for(RG int i = 0; i < n; ++i) printf("%lld %lld\n", ans1[i], ans2[i] == ans2[n] ? 0 : ans2[i]);
  71. return 0;
  72. }

正解,把\(height\)从大到小排序

每次合并\(height\)两边的集合,因为从大到小,所以两边集合的\(LCP\)一定就是这个\(height\),因为有负数权值,维护集合的最大值,最小值组合

  1. # include <bits/stdc++.h>
  2. # define RG register
  3. # define IL inline
  4. # define Fill(a, b) memset(a, b, sizeof(a))
  5. using namespace std;
  6. typedef long long ll;
  7. const int _(3e5 + 5);
  8. IL int Input(){
  9. RG int x = 0, z = 1; RG char c = getchar();
  10. for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
  11. for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
  12. return x * z;
  13. }
  14. int a[_], n, s[_], rk[_], sa[_], height[_], tmp[_], t[_];
  15. ll ans1[_], ans2[_];
  16. int fa[_], id[_], size[_], mx[_], mn[_];
  17. char ss[_];
  18. IL int Cmp(RG int i, RG int j, RG int k){
  19. return tmp[i] == tmp[j] && i + k <= n && j + k <= n && tmp[i + k] == tmp[j + k];
  20. }
  21. IL int _Cmp(RG int x, RG int y){
  22. return height[x] > height[y];
  23. }
  24. IL void Suffix_Sort(){
  25. RG int m = 26;
  26. for(RG int i = 1; i <= n; ++i) ++t[rk[i] = s[i]];
  27. for(RG int i = 1; i <= m; ++i) t[i] += t[i - 1];
  28. for(RG int i = n; i; --i) sa[t[rk[i]]--] = i;
  29. for(RG int k = 1; k <= n; k <<= 1){
  30. RG int l = 0;
  31. for(RG int i = n - k + 1; i <= n; ++i) tmp[++l] = i;
  32. for(RG int i = 1; i <= n; ++i) if(sa[i] > k) tmp[++l] = sa[i] - k;
  33. for(RG int i = 0; i <= m; ++i) t[i] = 0;
  34. for(RG int i = 1; i <= n; ++i) ++t[rk[tmp[i]]];
  35. for(RG int i = 1; i <= m; ++i) t[i] += t[i - 1];
  36. for(RG int i = n; i; --i) sa[t[rk[tmp[i]]]--] = tmp[i];
  37. swap(tmp, rk), rk[sa[1]] = l = 1;
  38. for(RG int i = 2; i <= n; ++i) rk[sa[i]] = Cmp(sa[i - 1], sa[i], k) ? l : ++l;
  39. if(l >= n) break;
  40. m = l;
  41. }
  42. for(RG int i = 1, h = 0; i <= n; ++i){
  43. if(h) --h;
  44. while(s[i + h] == s[sa[rk[i] - 1] + h]) ++h;
  45. height[rk[i]] = h;
  46. }
  47. }
  48. IL int Find(RG int x){
  49. return fa[x] == x ? x : fa[x] = Find(fa[x]);
  50. }
  51. int main(RG int argc, RG char* argv[]){
  52. Fill(ans2, -127), n = Input(), scanf(" %s", ss + 1);
  53. for(RG int i = 1; i <= n; ++i) s[i] = ss[i] - 'a' + 1, a[i] = Input();
  54. for(RG int i = 1; i <= n; ++i) fa[i] = id[i] = i, size[i] = 1, mx[i] = mn[i] = a[i];
  55. Suffix_Sort(), sort(id + 2, id + n + 1, _Cmp);
  56. for(RG int i = 2; i <= n; ++i){
  57. RG int fx = Find(sa[id[i] - 1]), fy = Find(sa[id[i]]);
  58. ans1[height[id[i]]] += 1LL * size[fx] * size[fy];
  59. fa[fy] = fx, size[fx] += size[fy];
  60. ans2[height[id[i]]] = max(ans2[height[id[i]]], max(1LL * mx[fx] * mx[fy], 1LL * mx[fx] * mn[fy]));
  61. ans2[height[id[i]]] = max(ans2[height[id[i]]], max(1LL * mn[fx] * mx[fy], 1LL * mn[fx] * mn[fy]));
  62. mx[fx] = max(mx[fx], mx[fy]);
  63. mn[fx] = min(mn[fx], mn[fy]);
  64. }
  65. for(RG int i = n - 1; ~i; --i) ans1[i] += ans1[i + 1], ans2[i] = max(ans2[i], ans2[i + 1]);
  66. for(RG int i = 0; i < n; ++i) printf("%lld %lld\n", ans1[i], ans2[i] == ans2[n] ? 0 : ans2[i]);
  67. return 0;
  68. }

Bzoj4199:[NOI2015]品酒大会的更多相关文章

  1. [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集

    [UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...

  2. [UOJ#131][BZOJ4199][NOI2015]品酒大会

    [UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...

  3. [bzoj4199][Noi2015]品酒大会_后缀自动机_后缀树_树形dp

    品酒大会 bzoj-4199 Noi-2015 题目大意:给定一个字符串,如果其两个子串的前$r$个字符相等,那么称这两个子串的开头两个位置$r$相似.如果两个位置勾兑在一起那么美味度为两个位置的乘积 ...

  4. [BZOJ4199][NOI2015]品酒大会

    #131. [NOI2015]品酒大会 统计 描述 提交 自定义测试 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项, ...

  5. bzoj4199: [Noi2015]品酒大会(后缀数组)

    题目描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainb ...

  6. BZOJ4199 [Noi2015]品酒大会 【后缀数组 + 单调栈 + ST表】

    题目 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品 酒家"和"首席猎手"两个奖项,吸 ...

  7. 并不对劲的bzoj4199: [Noi2015]品酒大会

    传送门-> 又称普及大会. 这题没什么好说的……后缀自动机裸题……并不对劲的人太菜了,之前照着标程逐行比对才过了这道题,前几天刚刚把这题一遍写对…… 这题的输出和某两点相同后缀的长度有关,那么把 ...

  8. 2019.02.28 bzoj4199: [Noi2015]品酒大会(sam+线段树)

    传送门 题意:给一个串,每个位置有一个权值,当S[s...s+len−1]=S[t...t+len−1]&&S[s...s+len]̸=S[t..t+len]S[s...s+len-1 ...

  9. bzoj千题计划257:bzoj4199: [Noi2015]品酒大会

    http://www.lydsy.com/JudgeOnline/problem.php?id=4199 求出后缀数组的height 从大到小枚举,合并 维护组内 元素个数,最大.次大.最小.次小 # ...

  10. [BZOJ4199][Noi2015]品酒大会 树形DP+后缀自动机

    由于要找后缀的前缀,所以先用反串建立SAM. link边组成了后缀树. 两个子串的最长公共前缀是LCA的step 树形dp即可. #include<iostream> #include&l ...

随机推荐

  1. CocosCreator游戏开发---菜鸟学习之路(二)SocketIO简易教程

    请先参考教程司令部-SocketIO教程进行相关操作 开发完成后部分用户会出现持续输出 a userConnected的BUG 如下图所示 经过一段时间的BUG检查终于发现了问题所在.每个人碰到的情况 ...

  2. WPF---Xaml中改变ViewModel的值

    在开发中遇到实现如下需求的情景:一个输入框,旁边一个清空输入的按钮,当输入框中有内容时显示清空按钮,点击该按钮可以清空输入框内容,当输入框中无内容时隐藏按钮 当然这个需求使用wpf的绑定功能很容易实现 ...

  3. zabbix_server 挂了原因及解决方法(内存溢出)

    14721:20170714:095330.028 [file:dbconfig.c,line:452] zbx_mem_malloc(): out of memory (requested 80 b ...

  4. PHPStorm 常用 设置配置 和快捷键大全 Win/Mac

    [转自 http://blog.csdn.net/fenglailea/article/details/53350080] PHPStorm 下载及主题样式下载 http://www.lanmps.c ...

  5. [CJOJ2410]数列操作d

    [CJOJ2410]数列操作d 标签: 线段树 题解 没时间写题了,我来嘴巴AC吧. 注意区间加的这个值不是 确定的,随着元素位置的变化而改变. 只需要能维护这个东西剩下的就很好做了. 那么\(x*( ...

  6. CENTOS6.6下zabbix2.4.7搭建

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 安装依赖 安装Perl .apr / apr-util yum -y ...

  7. 使用mybatis插入自增主键ID的数据后返回自增的ID

    在开发中碰到用户注册的功能需要用到用户ID,但是用户ID是数据库自增生成的,这种情况上网查询后使用下面的方式配置mybatis的insert语句可以解决: <insert id="in ...

  8. 高并发WEB网站优化方案

    一.什么是高并发在互联网时代,所讲的并发.高并发,通常是指并发访问,也就是在某个时间点,有多少个访问同时到来.比如,百度首页同时有1000个人访问,那么也就是并发为1000.通常一个系统的日PV在千万 ...

  9. 关于C/S框架网单表绑定,查询

    这种绑定暂时支持单表,并且不支持主键自增长!保存,删除,查看,修改用框架现成的. 1.先生成tb.bll.dal三个类.框架有生成工具,在debug文件里面有个叫CSFramework.Tools.C ...

  10. filter-api文档

    git地址:https://github.com/jiqianqin/filters 不断优化中,欢迎加入讨论- filter-tags 效果图: 参数 说明 格式 备注 data 展示的数据 [{ ...