求出后缀数组后, 对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. XCode工程中ARC模式与非ARC模式共用(转)

    Xcode 项目中经常会融合一些老的代码,它们可能采用非ARC的模式.混合编译时,就会碰到编译出错的情况. 如何共用ARC模式和非ARC模式呢? XCode除了提供整个项目是否使用ARC模式的选择外, ...

  2. 批处理就是windows的杰作啊

    今天要为了解决vs不能同时开启调试和编写的问题,我就上网查找了一些批处理的命令,用批处理调用exe,和打开txt,虽然一行代码就解决了但是我没用过啊,很陌生. call  路径\a.exe  就相当于 ...

  3. Neo4j简介

    Neo4j简介 发表于2013年3月16日 11:52 p.m.    位于分类图数据库与图并行计算 现实中很多数据都是用图来表达的,比如社交网络中人与人的关系.地图数据.或是基因信息等等.RDBMS ...

  4. ios文本常见属性

    文本属性Attributes 1.NSKernAttributeName: @10 调整字距 kerning 字距调整 2.NSFontAttributeName : [UIFont systemFo ...

  5. C#扩展方法的理解 (转)

    “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.” 这是msdn上说的,也就是你可以对String,Int,DataRow,DataTable等这些 ...

  6. spring与hibernate整合事务管理的理解

    在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...

  7. 加密传输SSL协议2_传统加密

    原本到了睡觉的时间,但是做完了SSL的笔记还有GCC和Oracle等的好多的笔记,所以刻苦一点. The Priciple of Encryption/Decryption --conventiona ...

  8. Linux网络管理——ISO/OSI七层模型

    1. 网络基础 1. 网络基础 1.1 iso/osi七层模型 事前声明: ISO:国际标准化组织 OSI:开放系统互联模型 IOS:苹果操作系统 但是在计算机网络当中,IOS是互联网操作系统,是思科 ...

  9. 【JQ成长笔记】jQuery Validate验证插件

    validate是一款很好的jq插件,提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求.该插件捆绑了一套有用的验证方法,包括 URL 和电子邮件验证,同 ...

  10. C#开发者通用性代码审查清单

    这是为C#开发者准备的通用性代码审查清单,可以当做开发过程中的参考.这是为了确保在编码过程中,大部分通用编码指导原则都能注意到.对于新手和缺乏经验(0到3年工作经验)的开发者,参考这份清单编码会很帮助 ...