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 ...
 
随机推荐
- BZOJ 4239: 巴士走读 最短路
			
显然,我们可以将询问按照规定时间从小到大排序,依次处理. 那么我们显然要求合法的点中从 $n$ 号点出发到达点 $i$ 的最迟时间,我们令这个为 $f[i]$ 而 $f[i]$ 显然可以用最短路来求. ...
 - ES6--函数的参数
			
参数展开(扩展) 1.收集剩余的参数 function show(a, b, ...args) { console.log(a); console.log(b); console.log(args); ...
 - Joomla 3.0.0 --> 3.4.6-RCE复现
			
Joomla是一款网站管理系统CMS,最近曝出其3.00-3.4.6的joomla版本存在一个RCE漏洞. 并且大佬已将exp放在了github上,下载地址:https://www.exploit-d ...
 - CF1227F2 Wrong Answer on test 233 (Hard Version)
			
题意 \(n\)道题,每道题有\(k\)种选项,其中第\(i\)道题正确答案是\(a_i\),但是填答案的时候填错啦,第一道题的选择填到了第二道题...第\(n\)道题的选择填到了第一道题,求在\(k ...
 - kubernetes nodePort、targetPort、port、containerPort图解
			
1. nodePort 外部机器可访问的端口. 比如一个Web应用需要被其他用户访问,那么需要配置type=NodePort,而且配置nodePort=,那么其他机器就可以通过浏览器访问scheme: ...
 - 一个简易git服务器的搭建
			
查看本机ssh公钥,生成公钥 查看ssh公钥方法: 1. 打开git bash窗口 2. 进入.ssh目录: cd ~/.ssh 3. 找到id_rsa.pub文件: ls 4. 查看公钥:cat i ...
 - 小白月赛22 G : 仓库地址
			
G : 仓库地址 考察点: 二维中位数 坑点 : 做就 OK 析题得侃: 我们发现 x 和 y 是相互独立的,也就是说先移动 x 或者先移动 y 都是可以到达一个点的,所以我们可以先找到 横坐标的 中 ...
 - PIE-SDK For C++栅格数据的金字塔创建
			
1.功能简介 金字塔可用于改善性能,可以加快栅格数据的显示速度.随着放大操作的进行,各个更精细的分辨率等级将逐渐得到绘制;但性能将保持不变:目前PIE SDK支持栅格数据的金字塔创建,下面对栅格数据格 ...
 - loj6277 数列分块入门题1
			
裸题分块. #include <bits/stdc++.h> using namespace std; ],b[],n,m,t1,t2,t3,t4,sq; int main(){ ios: ...
 - BK: Data mining: concepts and techniques (1)
			
Chapter 1 data mining is knowledge discovery from data; The knowledge discovery process is an iterat ...