品酒大会 BZOJ 4199
品酒大会
【问题描述】

【输入格式】

【输出格式】

【样例输入】
10
ponoiiipoi
2 1 4 7 4 8 3 6 4 7
【样例输出】
45 56
10 56
3 32
0 0
0 0
0 0
0 0
0 0
0 0
0 0
【数据范围】

题解:
根据题意可得"r相似”也是“r - 1相似”
那么我们只要求出了所有最大为 r 相似的对数,就可以利用后缀和求出所有r相似的个数
考虑一瓶酒与另一瓶酒如果是 r 相似的,那么与其中一瓶酒 k (k > r) 相似的酒与另一瓶酒最大也为 r 相似
所以用后缀数组求出 height 数组
然后按 height 从大到小排序
每次按顺序找出两个 height 相似的点的祖先
height 相似的对数累加上两个祖先块内的点数乘积
height 相似的最大值为两个块的最小值乘积和最大值乘积的较大值
用并查集合并,处理点的个数、最大值和最小值(美味度有负数)
最后跑一遍后缀和
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
inline void Scan(int &x)
{
char c;
int o = ;
while((c = getchar()) < '' || c > '')
if(c == '-') o = -;
x = c - '';
while((c = getchar()) >= '' && c <= '') x = x * + c - '';
x *= o;
}
const int me = ;
int n;
int w[me];
int x[me];
int sa[me], he[me];
int val[me], fat[me], nex[me];
int rank[me];
long long ans_si[me], ans_mx[me];
char s[me];
struct Union
{
long long si, mx, mi;
};
Union un[me];
inline void Sa()
{
int m = ;
for(int i = ; i <= n; ++i) ++w[x[i] = s[i] - 'a' + ];
for(int i = ; i <= m; ++i) w[i] += w[i - ];
for(int i = n; i >= ; --i) sa[w[x[i]]--] = i;
for(int k = ; k <= n; k <<= )
{
int p = ;
for(int i = n; i >= n - k + ; --i) rank[++p] = i;
for(int i = ; i <= n; ++i)
if(sa[i] > k)
rank[++p] = sa[i] - k;
for(int i = ; i <= m; ++i) w[i] = ;
for(int i = ; i <= n; ++i) ++w[x[i]];
for(int i = ; i <= m; ++i) w[i] += w[i - ];
for(int i = n; i >= ; --i) sa[w[x[rank[i]]]--] = rank[i];
m = ;
for(int i = ; i <= n; ++i)
{
int u = sa[i], v = sa[i - ];
if(x[u] != x[v] || x[u + k] != x[v + k]) rank[u] = ++m;
else rank[u] = m;
}
if(n == m) break;
for(int i = ; i <= n; ++i) swap(x[i], rank[i]);
}
int tot = ;
int i, j;
for(i = ; i <= n; i ++)
{
if (tot) tot --;
j = sa[rank[i] - ];
while (s[j + tot] == s[i + tot]) tot ++;
he[rank[i]] = tot;
}
}
inline bool rule(const int &x, const int &y)
{
return he[x] > he[y];
}
inline int Find(const int &x)
{
return (x != fat[x]) ? fat[x] = Find(fat[x]) : x;
}
inline void Un(const int &x, const int &y)
{
un[x].si += un[y].si;
un[x].mx = max(un[x].mx, un[y].mx);
un[x].mi = min(un[x].mi, un[y].mi);
fat[y] = x;
}
int main()
{
Scan(n);
scanf("%s", s + );
for(int i = ; i <= n; ++i)
{
Scan(val[i]);
nex[i] = i + ;
fat[i] = i;
}
Sa();
for(int i = ; i <= n; ++i)
ans_mx[i] = -;
for(int i = ; i <= n; ++i)
un[i] = (Union) {, val[sa[i]], val[sa[i]]};
sort(nex + , nex + n, rule);
for(int i = ; i < n; ++i)
{
int x = Find(nex[i] - ), y = Find(nex[i]);
int z = he[nex[i]];
ans_si[z] += un[x].si * un[y].si;
ans_mx[z] = max(ans_mx[z], max(un[x].mi * un[y].mi, un[x].mx * un[y].mx));
Un(x, y);
}
for(int i = n - ; i >= ; --i)
{
ans_si[i] += ans_si[i + ];
ans_mx[i] = max(ans_mx[i], ans_mx[i + ]);
}
for(int i = ; i < n; ++i)
printf("%lld %lld\n", ans_si[i], ans_si[i] ? ans_mx[i] : );
}
品酒大会 BZOJ 4199的更多相关文章
- [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会
[LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会 题意 给定一个长度为 \(n\) 的字符串 \(s\), 对于所有 \(r\in[1,n]\) 求出 \(s\ ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- [BZOJ]4199 品酒大会(Noi2015)
讲道理是后缀数组裸题吧,虽然知道后缀数组的原理但是小C不会写是什么鬼.. 小C趁着做这题的当儿,学习了一下后缀数组. 网络上的后缀数组模板完全看不懂怎么破,全程照着黄学长的代码抄,感觉黄学长写得还是很 ...
- bzoj 4199 && NOI 2015 品酒大会
一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 ...
- bzoj 4199: [Noi2015]品酒大会
Description 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品酒家"和"首席猎手&quo ...
- 【刷题】BZOJ 4199 [Noi2015]品酒大会
Description 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品酒家"和"首席猎手&quo ...
- 4199. [NOI2015]品酒大会【后缀数组+并查集】
Description 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加.在大会的晚餐上,调酒师 ...
- 【BZOJ-4199】品酒大会 后缀数组 + 并查集合并集合
4199: [Noi2015]品酒大会 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 436 Solved: 243[Submit][Status] ...
- 【BZOJ4199】【NOI2015】品酒大会(后缀数组)
[BZOJ4199][NOI2015]品酒大会 题面 BZOJ Uoj 洛谷 题解 考虑最裸的暴力 枚举每次的长度 以及两个开始的位置 检查以下是否满足条件,如果可以直接更新答案 复杂度\(O(n^3 ...
随机推荐
- Python实现1-9数组形成的结果为100的所有运算式
问题: 编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性.例如:1 + 2 + 34–5 + 67–8 + 9 = 100. f ...
- HDU 6052 To my boyfriend(容斥+单调栈)
题意:对于一个n*m的方格,每个格子中都包含一种颜色,求出任意一个矩形包含不同颜色的期望. 思路: 啊啊啊啊啊,补了两天,总算A了这道题了,简直石乐志,前面的容斥还比较好写,后面的那个>13那个 ...
- iPhone Scrollbars with iScroll
Since we've had web browsers and JavaScript, we've been intent on replacing native browser functiona ...
- 使用custom elements和Shadow DOM自定义标签
具体的api我就不写 官网上面多 如果不知道这个的话也可以搜索一下 目前感觉这个还是相当好用的直接上码. <!DOCTYPE html> <html lang="en&q ...
- (30)zabbix Trapper 监控项配置
概述 zabbix获取数据有超时时间,如果一些数据需要执行比较长的时间才能获取的话,那么zabbix会出现异常,考虑到这种情况,zabbix增加了Trapper功能,客户端自己提交数据给zabbix, ...
- perl学习之:shift/unshift
perl中shift 和unshift 操作 2008-02-02 11:18:04| 分类: Perl语言|举报|字号 订阅 ############################### ...
- PERL学习之模式匹配
一.简介 模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即模式def.其用法如结合函数split将字符串用某模式分成多个单词:@array = split(/ /, $line); ...
- python 学习总结4
数字类型及操作 一.整数类型 (1)python中的整数与数学中的概念是一致的,可以正也可以负,没有取值范围. pow(x,y)函数是计算x的y次幂,想计算多大就多大. (2)在整数类型中有四种进 ...
- LeetCode(95) Unique Binary Search Trees II
题目 Given n, generate all structurally unique BST's (binary search trees) that store values 1-n. For ...
- pep-8要求归纳
代码布局缩进每个缩进级别使用4个空格. 连续行应使用Python的隐式行连接括号,括号和大括号,或使用悬挂缩进 来垂直对齐包装元素.当使用悬挂式缩进时,应考虑以下内容:第一行应该没有任何争论,应该使用 ...