据说用后缀自动机 + dp也能做

然而并不会

后缀数组的做法呢

就是先建个后缀数组,求出height值,此时如果直接找,复杂度是n ^ 2的,肯定会超时。

但是height大的值是不会对小的产生影响的,所以可以按height大小,从大到小合并两个区间,用并查集维护就可以了

代码如下

 #include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = ;
typedef long long ll;
char s[N];
ll a[N];
int n;
int sa[N], c[N], x[N], y[N]; struct E {
int h, l, r;
inline bool operator < (const E o) const {
return h > o.h;
}
} g[N];
inline void BuildSa(int m) {
for (int i = ; i < m; i++) c[i] = ;
for (int i = ; i < n; i++) c[x[i] = s[i]]++;
for (int i = ; i < m; i++) c[i] += c[i - ];
for (int i = n - ; i >= ; i--) sa[--c[x[i]]] = i;
for (int k = ; k <= n; k <<= ) {
int p = ;
for (int i = n - k; i < n; i++) y[p++] = i;
for (int i = ; i < n; i++) if (sa[i] >= k) y[p++] = sa[i] - k;
for (int i = ; i < m; i++) c[i] = ;
for (int i = ; i < n; i++) c[x[y[i]]]++;
for (int i = ; i < m; i++) c[i] += c[i - ];
for (int i = n - ; i >= ; i--) sa[--c[x[y[i]]]] = y[i];
p = ; swap(x, y);
x[sa[]] = ;
for (int i = ; i < n; i++)
x[sa[i]] = y[sa[i]] == y[sa[i - ]] && y[sa[i] + k] == y[sa[i - ] + k] ? p - : p++;
if (p >= n) break;
m = p;
}
} int height[N], rank[N];
inline void GetHeight() {
for (int i = ; i < n; i++) rank[sa[i]] = i;
int k = ;
for (int i = ; i < n; i++) {
if (k) k--;
int j = sa[rank[i] - ];
while (s[j + k] == s[i + k]) k++;
height[rank[i]] = k;
}
} ll fa[N], size[N], ans[N], ans1[N], ans2[N], minn[N], maxn[N];
void Union(int x, int y) {
fa[x] = y;
size[y] += size[x];
ans[y] = max(ans[y], max(maxn[y] * maxn[x], minn[y] * minn[x]));
maxn[y] = max(maxn[y], maxn[x]);
minn[y] = min(minn[y], minn[x]);
} int find(int x) {
return (fa[x] == x) ? x : find(fa[x]);
} int main() {
scanf("%d", &n);
getchar();
for (int i = ; i < n; i++)
scanf("%c", &s[i]), s[i] -= 'a' - ;
for (int i = ; i < n; i++)
scanf("%lld", &a[i]);
s[n++] = ;
BuildSa();
GetHeight();
for (int i = ; i < n; i++) {
g[i].h = height[i];
g[i].l = sa[i];
g[i].r = sa[i - ];
}
sort(g + , g + n);
for (int i = ; i < n; i++) fa[i] = i, size[i] = , maxn[i] = a[i], minn[i] = a[i];
memset(ans, 0x80, sizeof(ans));
memset(ans2, 0x80, sizeof(ans2));
for (int i = ; i < n; i++) {
int x = find(g[i].l);
int y = find(g[i].r);
ans1[g[i].h] += (ll)size[x] * size[y];
Union(x, y);
ans2[g[i].h] = max(ans2[g[i].h], ans[y]);
}
for (int i = n - ; i >= ; i--) {
ans1[i] += ans1[i + ];
if (ans1[i + ]) ans2[i] = max(ans2[i], ans2[i + ]);
}
for (int i = ; i < n - ; i++) printf("%lld %lld\n", ans1[i], ans1[i] ? ans2[i] : );
return ;
}

bzoj4199: [Noi2015]品酒大会 (并查集 && 后缀数组)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. javascript 问题汇总(1)

    1    jquery ajax提交有参数的请求,提示错误“Unsupported Media Type“ 解决:ajax 设置添加  contentType: "application/j ...

  2. C#中怎样将数组的顺序打乱随机排序

    场景 在ZedGraph随机生成颜色时需要从颜色数组中取颜色对象. Color数组存取的是System.Drawing.Color的颜色. 其顺序是相邻的颜色,颜色差距不大,在取颜色时按顺序取颜色时, ...

  3. CVE-2019-0708 远程桌面代码执行漏洞复现

    0x01 首先是靶机,这里的靶机是使用清水表哥提供的win7sp1的系统 漏洞环境使用VM安装Windows7 SP1模拟受害机Windows7 SP1下载链接:ed2k://|file|cn_win ...

  4. 假期学习【十】首都之窗百姓信件JavaWweb+Echarts图表展示

    今天主要对昨天爬取的数据进行处理,处理后用Echart图表展示, 效果如下:

  5. 2018ICPC南京站Problem A. Adrien and Austin

    题意: n个石头再1-n的位置上,两个人轮流取时候,必须取连续的一段,最多取k个,不能取为输,问谁会赢 解析: 当k大于等于2时,先手总能把石头分成相等的两部分,此时后手无论怎么走,先手在对称的位置选 ...

  6. 2.Ubuntu安装 Docker

    平台支持 Docker CE 支持多种平台,如下表所示 桌面 平台 架构 Docker Desktop for Mac (macOS) X64 Docker Desktop for Windows ( ...

  7. [CF1304C] Air Conditioner

    维护一区间 \([l,r]\) 人按照时间升序 考虑 \((l_i, h_i, t_i)\),当前的所有区间与这个区间取交 推到 \(t_{i+1}\) 时,所有区间的端点向两边扩张即可 注意把空掉的 ...

  8. PHP获取小程序码并返回前端显示图片

    小程序的二维码分为小程序码和二维码: 生成小程序二维码文档中说后端来生成. 参考 小程序开发文档资料:https://developers.weixin.qq.com/miniprogram/dev/ ...

  9. WordPress 背后的故事竟然是这样

    原文链接:The Story Behind the New WordPress.com 译者:杰微刊-Leo Xu 一年半以前,我们对使用 WordPress 构建网站所需要采用的技术和开发流程进行大 ...

  10. 配置maven时,报JAVA_HOME错误

    其实原因很简单,是之前java的jdk配置不合规范! 一.我是win10系统. 二.我的java jdk放在D盘,环境变量里,JAVA_HOME是D:\Program Files\Java\jdk1. ...