题意

两个长度为$r$的子串相等称为$r$相似,两个$r$相似的权值等于子串开头位置权值乘积,给定字符串和每个位置权值,求$r$相似子串数量和最大权值乘积


对反串建立后缀自动机得到后缀树,后缀树上两个状态的lca的长度len就是原串的两个子串的lcp,在树上进行dp,parent树上每个状态代表长度为$maxlen_s-maxlen_{pa_s}$长度的一段子串,对于相似子串数量,$r$相似子串的数量$ans_r+=Right_u\times Right_v,maxlen_u==r$,对于最大权值乘积,维护每个状态的最大值最小值,每次用最大值最大值的乘积和最小值乘最小值的乘积更新答案,最后将答案累计

时间复杂度$O(n)$

代码

#include <bits/stdc++.h>
#define inf (LL)1000000000000000001
using namespace std;
typedef long long LL;
const int N = 1001000;
int ch[N][30], pa[N], maxlen[N], sz, last, Right[N], mark[N], val[N];
inline void init_sam() {
memset(ch, 0, sizeof(ch));
last = sz = 1;
}
inline void extend(int c, int x) {
int p = last, np = ++sz; last = np; maxlen[np] = maxlen[p] + 1; mark[np] = 1; val[np] = x;
while(p && !ch[p][c]) ch[p][c] = np, p = pa[p];
if(!p) {pa[np] = 1; return;}
int q = ch[p][c];
if(maxlen[q] == maxlen[p] + 1) {
pa[np] = q;
}else {
int nq = ++sz;
memcpy(ch[nq], ch[q], sizeof(ch[q]));
pa[nq] = pa[q]; maxlen[nq] = maxlen[p] + 1; pa[q] = pa[np] = nq;
while(ch[p][c] == q) ch[p][c] = nq, p = pa[p];
}
}
int cnt, head[N], nxt[N], to[N];
inline void init_edge() {cnt = 0; memset(head, -1, sizeof(head));}
inline void add(int u, int v) {to[cnt] = v; nxt[cnt] = head[u]; head[u] = cnt++;}
int n, a[N];
LL ans1[N], ans2[N], Max[N], Min[N];
char str[N];
void dfs(int u) {
Right[u] = 0; Max[u] = -inf; Min[u] = inf;
if(mark[u]) Right[u] = 1, Max[u] = Min[u] = val[u];
for(int i = head[u]; ~i; i = nxt[i]) {
int v = to[i]; dfs(v);
if(Max[u] != -inf && Max[v] != -inf && Min[u] != inf && Min[v] != inf) {
ans2[maxlen[u]] = max(ans2[maxlen[u]], max(Max[u] * Max[v], Min[u] * Min[v]));
}
Max[u] = max(Max[u], Max[v]); Min[u] = min(Min[u], Min[v]);
ans1[maxlen[u]] += 1LL * Right[u] * Right[v];
Right[u] += Right[v];
}
}
int main() {
init_sam();
init_edge();
scanf("%d", &n);
scanf("%s", str + 1);
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for(int i = n; i >= 1; --i) extend(str[i] - 'a', a[i]);
for(int i = 2; i <= sz; ++i) add(pa[i], i);
for(int i = 0; i <= n; ++i) ans2[i] = -inf;
dfs(1);
for(int i = n - 1; i >= 0; --i) ans1[i] += ans1[i + 1], ans2[i] = max(ans2[i], ans2[i + 1]);
for(int i = 0; i < n; ++i) {
if(ans1[i])printf("%lld %lld\n", ans1[i], ans2[i]);
else printf("0 0\n");
}
return 0;
}

【BZOJ 4199】[Noi2015]品酒大会 后缀自动机+DP的更多相关文章

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

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

  2. BZOJ 4199: [Noi2015]品酒大会 后缀自动机_逆序更新

    一道裸题,可以考虑自底向上去更新方案数与最大值. 没啥难的 细节........ Code: #include <cstdio> #include <algorithm> #i ...

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

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

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

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

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

    题目大意: 给定一个长为n的字符串,每个下标有一个权\(w_i\),定义下标\(i,j\)是r相似的仅当\(r \leq LCP(suf(i),suf(j))\)且这个相似的权为\(w_i,w_j\) ...

  6. BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )

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

  7. uoj 131/bzoj 4199 [NOI2015]品酒大会 后缀树+树d

    题目大意 见uoj131 分析 题目的提示还是很明显的 \(r\)相似就就代表了\(0...r-1\)相似 建出后缀树我们能dfs算出答案 再后缀和更新一下即可 注意 细节挺多的,但数据很良心 不然我 ...

  8. 【bzoj4199】[Noi2015]品酒大会 后缀自动机求后缀树+树形dp

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

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

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

随机推荐

  1. 【转】python测试开发面试题

    出处:http://my.oschina.net/u/1433482/blog/467954?fromerr=WrfxL2Kw 试卷时间 60分钟,请不要在试卷上作答,用A4纸做答题纸作答. 一,中文 ...

  2. 编程算法 - 二叉树的最低公共祖先 代码(C)

    二叉树的最低公共祖先 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉树的最低公共祖先(lowest common ancestor), 首先先序遍 ...

  3. 一篇很不错的关于WPF DataGrid的文章,包含validation

    https://www.codeproject.com/Articles/30905/WPF-DataGrid-Practical-Examples

  4. 自定义WPF ListBox的选择样式

    (下图:进行多项选择的ListBox) 首先介绍一种简单地方法:就是通过自定义SystemColors类的参数来自定义WPF ListBox选择颜色的,SystemColors的HighlightBr ...

  5. Matrix4x4矩阵 api

    Matrix4x4 矩阵api介绍 Namespace: UnityEngine Description 描述 A standard 4×4 transformation matrix. 一个标准的4 ...

  6. Pairs of Integers

    Pairs of Integers You are to find all pairs of integers such that their sum is equal to the given in ...

  7. 开始翻译《Beginning SharePoint 2013 Development》

    伙同涂曙光@kaneboy 和柴晓伟@WindieChai 翻译Beginning SharePoint 2013 Development 作者是Steve Fox,传说中的Andrew Connel ...

  8. zoj 3716 Ribbon Gymnastics【神奇的计算几何】

    题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3716 来源:http://acm.hust.edu.cn/vjudg ...

  9. JAVA NIO 简介 (netty源码死磕1.1)

    [基础篇]netty 源码死磕1.1:  JAVA NIO简介 1. JAVA NIO简介 Java 中 New I/O类库 是由 Java 1.4 引进的异步 IO.由于之前老的I/O类库是阻塞I/ ...

  10. Django在不启动server的情况下调用方法

    from django.conf import settingsfrom django import template settings.configure() a = template.Templa ...