求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N))

-----------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
 
using namespace std;
 
typedef long long ll;
 
const ll INF = -1LL << 60;
const int maxn = 300009;
 
char S[maxn];
int w[maxn], N;
int cnt[maxn], Sa[maxn], Rank[maxn], Height[maxn];
int mx[maxn], mn[maxn], fa[maxn], sz[maxn], r[maxn];
ll ans[maxn], tot[maxn];
 
void Init() {
scanf("%d%s", &N, S);
for(int i = 0; i < N; i++) scanf("%d", w + i);
S[N++] = '$';
}
 
void Build() {
int m = 255, *x = Height, *y = Rank;
for(int i = 0; i < m; i++) cnt[i] = 0;
for(int i = 0; i < N; i++) cnt[x[i] = S[i]]++;
for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
for(int i = N; i--; ) Sa[--cnt[x[i]]] = i;
for(int k = 1, p = 0; k <= N; k <<= 1, p = 0) {
for(int i = N - k; i < N; i++) y[p++] = i;
for(int i = 0; i < N; i++)
if(Sa[i] >= k) y[p++] = Sa[i] - k;
for(int i = 0; i < m; i++) cnt[i] = 0;
for(int i = 0; i < N; i++) cnt[x[y[i]]]++;
for(int i = 1; i < m; i++) cnt[i] += cnt[i - 1];
for(int i = N; i--; ) Sa[--cnt[x[y[i]]]] = y[i];
swap(x, y), x[Sa[0]] = 0, p = 1;
for(int i = 1; i < N; i++) {
if(y[Sa[i]] != y[Sa[i - 1]] || y[Sa[i] + k] != y[Sa[i - 1] + k]) p++;
x[Sa[i]] = p - 1;
}
if((m = p) >= N) break;
}
for(int i = 0; i < N; i++) Rank[Sa[i]] = i;
Height[0] = 0;
for(int i = 0, h = 0; i < N; i++) if(Rank[i]) {
if(h) h--;
while(S[i + h] == S[Sa[Rank[i] - 1] + h]) h++;
Height[Rank[i]] = h;
}
}
 
int Find(int x) {
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
 
bool Cmp(const int &l, const int &r) {
return Height[l] > Height[r];
}
 
inline void Max(ll &x, ll t) {
if(t > x) x = t;
}
inline void Max(int &x, int t) {
if(t > x) x = t;
}
inline void Min(int &x, int t) {
if(t < x) x = t;
}
 
void Work() {
for(int i = 0; i < N; i++) {
sz[i] = 1;
r[i] = fa[i] = i;
mx[i] = mn[i] = w[i];
tot[i] = 0;
ans[i] = INF;
}
sort(r, r + N, Cmp);
for(int i = 0; i < N; i++) if(r[i] > 1) {
int u = Find(Sa[r[i]]), v = Find(Sa[r[i] - 1]);
if(u == v) continue;
tot[Height[r[i]]] += ll(sz[u]) * sz[v];
Max(ans[Height[r[i]]], max(ll(mx[u]) * mx[v], ll(mn[u]) * mn[v]));
fa[u] = v, sz[v] += sz[u];
Max(mx[v], mx[u]);
Min(mn[v], mn[u]);
}
for(int i = Height[r[0]]; i--; )
tot[i] += tot[i + 1], Max(ans[i], ans[i + 1]);
for(int i = 0; i + 1 < N; i++)
printf("%lld %lld\n", tot[i], ans[i] != INF ? ans[i] : 0);
}
 
int main() {
Init();
Build();
Work();
return 0;
}

-----------------------------------------------------------------------------------

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

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

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

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

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

  3. 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集

    [BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...

  4. [NOI2015] 品酒大会 - 后缀数组,并查集,STL,启发式合并

    [NOI2015] 品酒大会 Description 对于每一个 \(i \in [0,n)\) 求有多少对后缀满足 LCP 长度 \(\le i\) ,并求满足条件的两个后缀权值乘积的最大值. So ...

  5. BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)

    BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...

  6. 【学术篇】NOI2015 品酒大会 后缀数组+并查集

    省选前大致是刷不了几道题了... 所以就找一些裸一点的题目练练板子算了= = 然而这题一点都不裸, 也并不怎么好写... 于是就浪费了将近一下午的时间... 然而还不是因为后缀数组板子不熟= = 首先 ...

  7. NOI 2015 品酒大会 (后缀数组+并查集)

    题目大意:略 40分暴力还是很好写的,差分再跑个后缀和 和 后缀最大值就行了 一种正解是后缀数组+并查集 但据说还有后缀数组+单调栈的高端操作蒟蒻的我当然不会 后缀数组求出height,然后从大到小排 ...

  8. BZOJ.4199.[NOI2015]品酒大会(后缀自动机 树形DP)

    BZOJ 洛谷 后缀数组做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 只考虑求极长相同子串,即所有后缀之间的LCP. 而后缀的LCP在后缀树的LCA处.同差异这道题,在每个点处 ...

  9. Uoj #131. 【NOI2015】品酒大会 后缀数组,并查集

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

随机推荐

  1. SpringMVC中的异步提交表单

    1.前言 近期在做一个项目,前台框架用的是EasyUI+SpringMVC,因为对SpringMVC不太了解,所以刚開始接触的时候有点吃力,在此通过一个EasyUi中的DataGrid表格来总结一下. ...

  2. 前端制作中,IE6还有必要兼容吗?

    国内市场对IE 6~7支持还有一定需求,但对于一个前端开发者,我们应该去推动这个行业向前发展,而不是一味迁就.妥协. 曾经,能够提供支持老版本 IE 是一个前端开发者的必备技能.随着移动互联网大潮来临 ...

  3. 详解VB.net编写DLL(动态链接库、应用程序扩展)文件

    首先,我们启动VS(Visual-Studio简称),我使用的是VS2008版本. 新建一个项目-选择内裤(额...不好意思)→类库 ,名称就默认吧. 编写类库没有窗体设计,因此我们不能使用工具箱中的 ...

  4. C语言-进制

    本文目录 • 一.十进制 • 二.二进制 • 三.八进制 • 四.十六进制 • 五.进制总结 • 六.变量与进制 • 七.printf的简单使用上一讲简单介绍了常量和变量,这讲补充一点计算机的基础知识 ...

  5. const和非const函数重载

    成员函数后面加const,表示在该函数中不能对类的数据成员进行改变,比如下面的代码: #include <stdio.h> class A { private: mutable int a ...

  6. Linux学习之服务器端口查看的方法

    1.用netstat查看: [grid@rac121 admin]$ netstat -anp | grep oracle (Not all processes could be identified ...

  7. html语法之--使用图像映射

    1 什么是图像映射所谓图像映射是指在一幅图中定义若干个区域,每个区域中指定一个不同的超链接,当单击不同的区域时便可以跳转到相应的目标页面. 2 创建图像映射 2.1 定义映射区域 定义映射区域使用MA ...

  8. php数组分页类

    <?php class ArrayPage{ public $totalPage;//全部页数 public $lists;//每页显示数目 public $arr = array();//分页 ...

  9. UEFI引导系统

    UEFI引导系统 1 2 3 4 5 6 7 分步阅读 现在的电脑大多数使用了UEFI引导系统(原来都是使用BIOS),从而加快启动速度,但同时也给用惯BIOS的用户带来很多困惑!为啥电脑不能识别制作 ...

  10. Oracle EBS-SQL (BOM-6):检查物料失效但BOM中未失效的数据.sql

    select msi.segment1                   装配件编码 , msi.description                  装配件描述 , msi.item_type ...