BZOJ 4199: [Noi2015]品酒大会 后缀自动机_逆序更新
一道裸题,可以考虑自底向上去更新方案数与最大值。
没啥难的
细节........
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 1000006
#define inf -0x3f3f3f3f3f3f3f3fll
#define ll long long
using namespace std;
int n,is[maxn],appear[maxn];
long long val[maxn],ans1[maxn],ans2[maxn],maxv[maxn],minv[maxn];
char str[maxn];
// struct Graph{
// int head[maxn],to[maxn],nex[maxn],edges;
// void addedge(int u,int v) { nex[++edges] = head[u],head[u] = edges,to[edges] = v; }
// }G;
struct SAM{
int f[maxn],cnt[maxn],ch[maxn][30],len[maxn],tot,last;
int C[maxn],rk[maxn];
void init() {
tot = last = 1;
for(int i = 0;i < maxn; ++i) ans2[i] = inf;
}
void ins(int c,int cur){
int np = ++tot,p = last; len[np] = len[last] + 1, last = tot;
while(p && !ch[p][c]) ch[p][c] = np,p = f[p];
if(!p) f[np] = 1;
else{
int q = ch[p][c];
if(len[q] == len[p] + 1) f[np] = q;
else {
int nq = ++tot;
len[nq] = len[p] + 1;
is[nq] = 1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
f[nq] = f[q],f[q] = f[np] = nq;
while(p && ch[p][c] == q) ch[p][c] = nq,p = f[p];
}
}
++cnt[last];
maxv[last] = val[cur];
minv[last] = val[cur];
}
void build(){
for(int i = 1;i <= tot; ++i) ++C[len[i]];
for(int i = 1;i <= tot; ++i) C[i] += C[i - 1];
for(int i = 1;i <= tot; ++i) rk[C[len[i]]--] = i;
for(int i = tot;i >= 1; --i) {
int p = rk[i];
ans1[len[f[p]]] += (long long)cnt[f[p]] * cnt[p];
cnt[f[p]] += cnt[p];
if(is[f[p]] && !appear[f[p]])
{
appear[f[p]] = 1;
minv[f[p]] = minv[p];
maxv[f[p]] = maxv[p];
continue;
}
ans2[len[f[p]]] = max(ans2[len[f[p]]],maxv[p]*maxv[f[p]]);
ans2[len[f[p]]] = max(ans2[len[f[p]]],minv[p]*minv[f[p]]);
maxv[f[p]] = max(maxv[f[p]],maxv[p]);
minv[f[p]] = min(minv[f[p]],minv[p]);
}
}
}sam;
int main(){
// setIO("input");
scanf("%d",&n),scanf("%s",str),sam.init();
for(int i = 0;i < n; ++i) scanf("%lld",&val[i]);
for(int i = n - 1;i >= 0; --i) sam.ins(str[i] - 'a',i);
sam.build();
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("%d %d\n",0,0);
else printf("%lld %lld\n",ans1[i],ans2[i]);
}
return 0;
}
BZOJ 4199: [Noi2015]品酒大会 后缀自动机_逆序更新的更多相关文章
- BZOJ.4199.[NOI2015]品酒大会(后缀自动机 树形DP)
BZOJ 洛谷 后缀数组做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 只考虑求极长相同子串,即所有后缀之间的LCP. 而后缀的LCP在后缀树的LCA处.同差异这道题,在每个点处 ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)
BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...
- BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )
求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N)) ------------------------- ...
- bzoj 4199: [Noi2015]品酒大会 后缀树
题目大意: 给定一个长为n的字符串,每个下标有一个权\(w_i\),定义下标\(i,j\)是r相似的仅当\(r \leq LCP(suf(i),suf(j))\)且这个相似的权为\(w_i,w_j\) ...
- uoj 131/bzoj 4199 [NOI2015]品酒大会 后缀树+树d
题目大意 见uoj131 分析 题目的提示还是很明显的 \(r\)相似就就代表了\(0...r-1\)相似 建出后缀树我们能dfs算出答案 再后缀和更新一下即可 注意 细节挺多的,但数据很良心 不然我 ...
- 【BZOJ 4199】[Noi2015]品酒大会 后缀自动机+DP
题意 两个长度为$r$的子串相等称为$r$相似,两个$r$相似的权值等于子串开头位置权值乘积,给定字符串和每个位置权值,求$r$相似子串数量和最大权值乘积 对反串建立后缀自动机得到后缀树,后缀树上两个 ...
- bzoj 4199: [Noi2015]品酒大会
Description 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品酒家"和"首席猎手&quo ...
- 【刷题】BZOJ 4199 [Noi2015]品酒大会
Description 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发"首席品酒家"和"首席猎手&quo ...
随机推荐
- 利用PBFunc在Powerbuilder中进行FTP操作
PBFunc.dll包含了FTP的操作,使用FTP时主要需要以下步骤: 1.调用of_Login函数登录Ftp服务器 2.调用FTP的各种方法 3.Ftp操作完毕后调用of_LoginOut方法进行注 ...
- Unity 自己旋转 方法
transform.Rotate(Vector3.up * Time.deltaTime * 100);
- C++的头文件(转)
这几天在写比较困难的一部分,所以也没有时间总结一些东西了,不过昨天翻我的笔记本,发现了一篇还不错的笔记,给大家看看. C/C++头文件一览 C.传统 C++ #include <assert.h ...
- 将数据内容动态添加到HTML中
// 申明一个数组用来装遍历的元素 var li = []; //遍历元素并加载到标签中 for(var i = 0; i<navGroup.self_first_nav.length; i++ ...
- LeetCode Golang 9.回文数
9. 回文数 第一种办法 :itoa 转换为字符串进行处理: package main import ( "strconv" "fmt" ) //判断一个整数是 ...
- 路飞学城Python-Day32
36-进程池线程池 开多线程实现并发的效率是高的,当用户没有那么多的时候,服务器是可以承受压力的 但是一定要以某种方式来设置并发数,让服务器能够实现稳定的运行,控制服务器的线程数 设置池,往里面放池的 ...
- 笔记本安装Archlinux笔记
同步更新于wendster大佬的个人博客 搬运自我的洛谷博客 可能会不定期更新! 因为前几天给我的小炸鸡加了一根内存条:而且先前装的Xubuntu是32位的,使用极其不方便:再加上wendster大佬 ...
- js应用中的小细节-时间戳的转换和input输入框有效数字
1 input输入框内value值保留有效数字,js自带的方法.toFixed(),但是直接使用会报错,因为不论输入框内输入汉字.字母还是数字,类型都是string.解决的办法是将其转换为number ...
- 搭建ELK日志分析平台(上)—— ELK介绍及搭建 Elasticsearch 分布式集群
笔记内容:搭建ELK日志分析平台(上)-- ELK介绍及搭建 Elasticsearch 分布式集群笔记日期:2018-03-02 27.1 ELK介绍 27.2 ELK安装准备工作 27.3 安装e ...
- Eclipse配置Maven私服
Eclipse配置Maven私服 前言: 搭建Maven私有仓库的主要目的,是为了在团队多人开发时,只要内网的私有仓库有下载过依赖的jar包,就直接从私有仓库获取,不再通过外网的中央仓库.如果私服上面 ...