品酒大会

【问题描述】

【输入格式】

【输出格式】

【样例输入】

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的更多相关文章

  1. [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会

    [LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会 题意 给定一个长度为 \(n\) 的字符串 \(s\), 对于所有 \(r\in[1,n]\) 求出 \(s\ ...

  2. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  3. [BZOJ]4199 品酒大会(Noi2015)

    讲道理是后缀数组裸题吧,虽然知道后缀数组的原理但是小C不会写是什么鬼.. 小C趁着做这题的当儿,学习了一下后缀数组. 网络上的后缀数组模板完全看不懂怎么破,全程照着黄学长的代码抄,感觉黄学长写得还是很 ...

  4. bzoj 4199 && NOI 2015 品酒大会

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

  5. bzoj 4199: [Noi2015]品酒大会

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

  6. 【刷题】BZOJ 4199 [Noi2015]品酒大会

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

  7. 4199. [NOI2015]品酒大会【后缀数组+并查集】

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

  8. 【BZOJ-4199】品酒大会 后缀数组 + 并查集合并集合

    4199: [Noi2015]品酒大会 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 436  Solved: 243[Submit][Status] ...

  9. 【BZOJ4199】【NOI2015】品酒大会(后缀数组)

    [BZOJ4199][NOI2015]品酒大会 题面 BZOJ Uoj 洛谷 题解 考虑最裸的暴力 枚举每次的长度 以及两个开始的位置 检查以下是否满足条件,如果可以直接更新答案 复杂度\(O(n^3 ...

随机推荐

  1. 清空iptables

    /sbin/iptables -P INPUT ACCEPT /sbin/iptables -F iptables -L

  2. 安装ruby开发环境

    如何快速正确的安装 Ruby, Rails 运行环境 对于新入门的开发者,如何安装 Ruby, Ruby Gems 和 Rails 的运行环境可能会是个问题,本页主要介绍如何用一条靠谱的路子快速安装 ...

  3. 对于WebAssembly编译出来的.wasm文件js如何调用

    WebAssembly也叫浏览器字节码技术 这里就不过多的解释了网上很多介绍 主要是让大家知道在js里面如何调用执行它,我之前看WebAssemblyAPI时候反正是看得一脸懵逼 也是为了大家能更快的 ...

  4. ELK踩过的各种坑 6.4版本

    一.elasticsearch 1.服务正常启动,但不能正常访问 [root@linux-node1 elasticsearch]# systemctl start elasticsearch [ro ...

  5. RN踩坑

    使用夜神 使用夜神作为模拟器,这个模拟器启动就会监听62001端口. 开发工具与模拟器的通信都是通过adb.夜神模拟器的安装目录/bin下有一个adb.exe,android sdk tools下也有 ...

  6. 【css】报错,错误代码77,CURLE_SSL_CACERT_BADFILE (77)解决方法

    CURLE_SSL_CACERT_BADFILE (77) - 读取 SSL CA 证书时遇到问题(可能是路径错误或访问权限问题) 在微信接口相关开发时容易出现此问题 这一般是因为服务更新了相关的软件 ...

  7. Python数据分析库之pandas,你该这么学!No.1

    写这个系列背后的故事 咦,面试系列的把基础部分都写完啦,哈哈答,接下来要弄啥嘞~ pandas吧 外国人开发的 翻译成汉语叫 熊猫 厉害厉害,很接地气 一个基于numpy的库 干啥的? 做数据分析用的 ...

  8. Python日志(logging)模块,shelve,sys模块

    菜鸟学python第十七天 1.logging 模块 logging模块即日志记录模块 用途:用来记录日志 为什么要记录日志: 为了日后复查,提取有用信息 如何记录文件 直接打开文件,往里写东西 直接 ...

  9. Python模块目录

    阅读目录 模块 模块语法 常用模块 collections模块 time模块 random模块 os模块 sys模块 序列化模块 shelve模块 pickle模块 json模块 configpars ...

  10. BNUOJ 19297 Code Refactoring

    Code Refactoring Time Limit: 3000ms Memory Limit: 131072KB   This problem will be judged on UVA. Ori ...