[NOI2015]品酒大会(后缀树+DP)
后缀自动机有一个性质。
就是如果倒建SAM两个串的lcp就是这两个串的结束节点的LCA。
然后就可以愉快的跑DP了。
对于每一个后缀树上的节点\(u\),它对\(len[u]\)的贡献是\(\sum_{v1}\sum_{v2\neq{v1}}size[v1]*size[v2]\)当然如果u就是一个后缀的结尾就要加上自己。
然后最大值怎么办?我们在每一个节点上维护最小次小,最大次大然后DP转移就行。
因为这题\(k\)相似就是\(k-1\)相似。最后还要对个数求个和,对最大值求一个\(max\)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define int long long
const int N=601000;
const int INF=1e18+10;
int cnt,head[N];
int tot=1,u=1,trans[N][27],size[N],len[N],fa[N];
int mx[N],mxx[N],mn[N],mnn[N],dp[N];
int ans[N],anss[N],n,a[N];
char s[N];
struct edge{
int to,nxt;
}e[N];
void add(int u,int v){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'||ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
void ins(int id,int c){
int x=++tot;len[x]=len[u]+1;
mx[x]=mn[x]=a[id];size[x]=1;mxx[x]=-INF;mnn[x]=INF;
for(;u&&trans[u][c]==0;u=fa[u])trans[u][c]=x;
if(u==0)fa[x]=1;
else{
int v=trans[u][c];
if(len[u]+1==len[v])fa[x]=v;
else{
int w=++tot;len[w]=len[u]+1;
mx[w]=-INF;mn[w]=INF;mxx[x]=-INF;mnn[x]=INF;
memcpy(trans[w],trans[v],sizeof(trans[w]));
fa[w]=fa[v];
fa[x]=fa[v]=w;
for(;u&&trans[u][c]==v;u=fa[u])trans[u][c]=w;
}
}
u=x;
}
void dfs(int u){
int tmp=size[u];
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
dfs(v);
dp[u]+=size[v]*tmp;
tmp+=size[v];
if(mx[v]>mx[u]){
mxx[u]=mx[u];
mx[u]=mx[v];
if(mxx[v]>mxx[u])mxx[u]=mxx[v];
}
else if(mx[v]>mxx[u])mxx[u]=mx[v];
if(mn[v]<mn[u]){
mnn[u]=mn[u];
mn[u]=mn[v];
if(mnn[v]<mnn[u])mnn[u]=mnn[v];
}
else if(mn[v]<mnn[u])mnn[u]=mn[v];
size[u]+=size[v];
}
ans[len[u]]+=dp[u];
if(size[u]!=1)anss[len[u]]=max(anss[len[u]],max(mx[u]*mxx[u],mn[u]*mnn[u]));
}
signed main(){
scanf("%lld",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
for(int i=n;i>=1;i--)ins(i,s[i]-'a'+1);
for(int i=1;i<=tot;i++)add(fa[i],i);
for(int i=0;i<=n+1;i++)anss[i]=-INF;
dfs(1);
for(int i=n;i>=0;i--)ans[i]+=ans[i+1],anss[i]=max(anss[i],anss[i+1]);
for(int i=0;i<n;i++)
if(ans[i]==0)printf("0 0\n");
else printf("%lld %lld\n",ans[i],anss[i]);
return 0;
}
[NOI2015]品酒大会(后缀树+DP)的更多相关文章
- 【BZOJ 4199】[Noi2015]品酒大会 后缀自动机+DP
题意 两个长度为$r$的子串相等称为$r$相似,两个$r$相似的权值等于子串开头位置权值乘积,给定字符串和每个位置权值,求$r$相似子串数量和最大权值乘积 对反串建立后缀自动机得到后缀树,后缀树上两个 ...
- uoj 131/bzoj 4199 [NOI2015]品酒大会 后缀树+树d
题目大意 见uoj131 分析 题目的提示还是很明显的 \(r\)相似就就代表了\(0...r-1\)相似 建出后缀树我们能dfs算出答案 再后缀和更新一下即可 注意 细节挺多的,但数据很良心 不然我 ...
- bzoj 4199: [Noi2015]品酒大会 后缀树
题目大意: 给定一个长为n的字符串,每个下标有一个权\(w_i\),定义下标\(i,j\)是r相似的仅当\(r \leq LCP(suf(i),suf(j))\)且这个相似的权为\(w_i,w_j\) ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集
[UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...
- [NOI2015] 品酒大会 - 后缀数组,并查集,STL,启发式合并
[NOI2015] 品酒大会 Description 对于每一个 \(i \in [0,n)\) 求有多少对后缀满足 LCP 长度 \(\le i\) ,并求满足条件的两个后缀权值乘积的最大值. So ...
- 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集
[BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...
- 【bzoj4199】[Noi2015]品酒大会 后缀自动机求后缀树+树形dp
题目描述(转自百度文库) 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒 ...
- BZOJ.4199.[NOI2015]品酒大会(后缀自动机 树形DP)
BZOJ 洛谷 后缀数组做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 只考虑求极长相同子串,即所有后缀之间的LCP. 而后缀的LCP在后缀树的LCA处.同差异这道题,在每个点处 ...
- 洛谷P2178 [NOI2015]品酒大会(后缀自动机 线段树)
题意 题目链接 Sol 说一个后缀自动机+线段树的无脑做法 首先建出SAM,然后对parent树进行dp,维护最大次大值,最小次小值 显然一个串能更新答案的区间是\([len_{fa_{x}} + 1 ...
随机推荐
- performSelector与objc_msgSend
- perform:(SEL)aSelector { if (aSelector) return objc_msgSend(self, aSelector); else return [self er ...
- Kattis - How Many Digits?
How Many Digits? Often times it is sufficient to know the rough size of a number, rather than its ex ...
- day03 Python3的安装
目录 Python的安装 Python下载 Python3安装 环境变量 添加环境变量 在CMD中运行Python Python的安装 Python可在多个操作系统(Windows,Linux,Mac ...
- c/c++连接mysql数据库设置及乱码问题(vs2013连接mysql数据库,使用Mysql API操作数据库)
我的安装环境: (1)vs2013(32位版) (vs2013只有32位的 没有64位的,但是它可以编译出64位的程序) : (2)mysql-5.7.15(64位) vs2013中的设置(按步骤来 ...
- Java校验8位字符串是否为正确的日期格式
import java.text.ParseException; import java.text.SimpleDateFormat; /** * 校验8位字符串是否为正确的日期格式 * @autho ...
- 2019-02-25 SQL:cast(itemvalue as decimal(19,4))
1.Operand data type nvarchar(max) is invalid for sum operator 要转换格式 2.Conversion failed when convert ...
- js常用特效-幻灯片
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- HDU 4335 Contest 4
利用降幂公式..呃,还是自己去搜题解吧.知道降幂公式后,就不难了. #include <iostream> #include <cstdio> #include <alg ...
- 编写html经常使用而又easy忘记的语句
设置文件字符编码: <meta charset="utf-8"> 内部样式表: <style type="text/css"> hr { ...
- UESTC 1143 数据传输 网络流 最大流 Dinic
数据传输 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...