bzoj4199: [Noi2015]品酒大会 (并查集 && 后缀数组)
据说用后缀自动机 + 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]品酒大会 (并查集 && 后缀数组)的更多相关文章
- [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集
[UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...
- [UOJ#131][BZOJ4199][NOI2015]品酒大会
[UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...
- bzoj4199: [Noi2015]品酒大会(后缀数组)
题目描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainb ...
- [bzoj4199][Noi2015]品酒大会_后缀自动机_后缀树_树形dp
品酒大会 bzoj-4199 Noi-2015 题目大意:给定一个字符串,如果其两个子串的前$r$个字符相等,那么称这两个子串的开头两个位置$r$相似.如果两个位置勾兑在一起那么美味度为两个位置的乘积 ...
- BZOJ4199 [Noi2015]品酒大会 【后缀数组 + 单调栈 + ST表】
题目 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品 酒家"和"首席猎手"两个奖项,吸 ...
- [BZOJ4199][NOI2015]品酒大会
#131. [NOI2015]品酒大会 统计 描述 提交 自定义测试 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项, ...
- 并不对劲的bzoj4199: [Noi2015]品酒大会
传送门-> 又称普及大会. 这题没什么好说的……后缀自动机裸题……并不对劲的人太菜了,之前照着标程逐行比对才过了这道题,前几天刚刚把这题一遍写对…… 这题的输出和某两点相同后缀的长度有关,那么把 ...
- bzoj千题计划257:bzoj4199: [Noi2015]品酒大会
http://www.lydsy.com/JudgeOnline/problem.php?id=4199 求出后缀数组的height 从大到小枚举,合并 维护组内 元素个数,最大.次大.最小.次小 # ...
- [BZOJ4199][Noi2015]品酒大会 树形DP+后缀自动机
由于要找后缀的前缀,所以先用反串建立SAM. link边组成了后缀树. 两个子串的最长公共前缀是LCA的step 树形dp即可. #include<iostream> #include&l ...
随机推荐
- 手写mybatis框架笔记
MyBatis 手写MyBatis流程 架构流程图 封装数据 封装到Configuration中 1.封装全局配置文件,包含数据库连接信息和mappers信息 2.封装*mapper.xml映射文件 ...
- 洛谷P1936 水晶灯火灵 P1775 古代人的难题_NOI导刊2010提高(02)【重题请做P1936】
首先我要说明,此题(古代人的难题)与水晶灯火灵是一模一样的! 古代人的难题 (File IO): input:puzzle.in output:puzzle.out 时间限制: 1000 ms 空间 ...
- 图像读取函数cv::imread()的几种使用方式
string imgpath = "C:\Users\Y\Pictures\miao.jpg"; OpenCV的imread()函数不支持单右斜线形式的路径,即不支持上述形式的路径 ...
- wfuzz的使用
用于模糊测试,测试过滤字符 转载:https://www.secpulse.com/archives/81560.html https://www.freebuf.com/sectool/173746 ...
- One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:
C:\Users\arn>webpack -v One CLI for webpack must be installed. These are recommended choices, del ...
- 用 ArcMap 发布 ArcGIS Server Feature Server Feature Access 服务
1. 安装Desktop, 2. 安装ArcGIS Server 3. 安装PostgreSQL 9.5 从 C:\Program Files (x86)\ArcGIS\Desktop10.5\Dat ...
- sql server针对字符串型数字排序(针对此字符串的长度不一致)
对于不规则的字符串数字排序,无法按照数字大的大小排序的原因是,字符串数字在数据库中按照ASCII码排序,从字符的第一个数字对比,首先就会将为首个数字相同的排在一起,在从这些字符串里面对比第二个数字,如 ...
- Costco这样的超级零售商,能不能干掉电商?
名创优品创始人叶国富曾说过,Costco只是没有来到中国(大陆),如果它来了,中国现在的零售业全部都会"死光".叶国富的话,似乎一语成箴. 随着Costco正式入华,其正在彻底搅动 ...
- set类型的应用场景 —— Redis实战经验
set类型是string类型的集合,其特点是集合元素无序且不重复,每个集合最多可以存储 232 - 1 个元素(40多亿),set类型主要有以下应用场景. 1. 好友/关注/粉丝/感兴趣的人集合 se ...
- ASP.NET Core 2.1 中的 HttpClientFactory (Part 4) 整合Polly实现瞬时故障处理
原文:https://www.stevejgordon.co.uk/httpclientfactory-using-polly-for-transient-fault-handling发表于:2018 ...