[LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会

题意

给定一个长度为 \(n\) 的字符串 \(s\), 对于所有 \(r\in[1,n]\) 求出 \(s\) 的所有LCP不小于 \(r\) 的后缀对的个数以及这些后缀对所能组成的最大权值.

一个后缀对 \((a,b)\) 的权值是它们左端点的权值的积.

\(n\le 3\times 10^5\).

题解

很久以前写的SAM沙雕题

因为要求LCP所以我们把这个串reverse一下用SAM搞.

根据后缀自动机的性质, 某两个后缀的LCP就是它们在SAM上对应结点的LCA的 \(len\).

那么对于计数的部分, 我们显然只要对于每个点都算出有多少个后缀以它为LCA就可以了.

后面求最大权值的部分看上去好像只要记录一下子树中的最大值和次大值就可以了, 然而权值可能有负数于是还得记录最小值和次小值.

计算出每个 \(len\) 的贡献后取后缀和就可以出答案了.

参考代码

#include <bits/stdc++.h>

const int MAXN=6e5+10;
typedef long long int64; struct Edge{
int from;
int to;
Edge* next;
};
Edge E[MAXN];
Edge* head[MAXN];
Edge* top=E; int n;
int cnt=1;
int root=1;
int last=1;
int v[MAXN];
char s[MAXN];
int len[MAXN];
int prt[MAXN];
int val[MAXN];
int size[MAXN];
int64 ans[MAXN];
int64 sum[MAXN];
int maxv[MAXN][2];
int minv[MAXN][2];
std::map<char,int> chd[MAXN]; void DFS(int);
void Insert(int,int);
void Extend(char,int); int main(){
memset(ans,0x80,sizeof(ans));
memset(maxv,0x80,sizeof(maxv));
memset(minv,0x7F,sizeof(minv));
scanf("%d",&n);
scanf("%s",s);
for(int i=0;i<n;i++)
scanf("%d",v+i);
for(int i=1;i<=n;i++)
Extend(s[n-i],v[n-i]);
for(int i=2;i<=cnt;i++)
Insert(prt[i],i);
DFS(root);
for(int i=n-1;i>=0;i--){
sum[i]+=sum[i+1];
ans[i]=std::max(ans[i],ans[i+1]);
}
for(int i=0;i<n;i++)
printf("%lld %lld\n",sum[i],sum[i]==0?0:ans[i]);
return 0;
} void UpdateMax(int x,int v){
maxv[x][1]=std::max(maxv[x][1],v);;
if(maxv[x][0]<maxv[x][1])
std::swap(maxv[x][0],maxv[x][1]);
} void UpdateMin(int x,int v){
minv[x][1]=std::min(minv[x][1],v);
if(minv[x][0]>minv[x][1])
std::swap(minv[x][0],minv[x][1]);
} void DFS(int root){
for(Edge* i=head[root];i!=NULL;i=i->next){
DFS(i->to);
sum[len[root]]+=1ll*size[root]*size[i->to];
size[root]+=size[i->to];
UpdateMin(root,minv[i->to][0]);
UpdateMin(root,minv[i->to][1]);
UpdateMax(root,maxv[i->to][0]);
UpdateMax(root,maxv[i->to][1]);
}
if(size[root]>1)
ans[len[root]]=std::max(ans[len[root]],std::max(1ll*minv[root][0]*minv[root][1],1ll*maxv[root][0]*maxv[root][1]));
} void Extend(char x,int v){
int p=last;
int np=++cnt;
size[last=np]=1;
len[np]=len[p]+1;
minv[np][0]=v;
maxv[np][0]=v;
while(p&&!chd[p].count(x))
chd[p][x]=np,p=prt[p];
if(p==0)
prt[np]=root;
else{
int q=chd[p][x];
if(len[q]==len[p]+1)
prt[np]=q;
else{
int nq=++cnt;
chd[nq]=chd[q];
prt[nq]=prt[q];
prt[q]=nq;
prt[np]=nq;
len[nq]=len[p]+1;
while(p&&chd[p][x]==q)
chd[p][x]=nq,p=prt[p];
}
}
} void Insert(int from,int to){
top->from=from;
top->to=to;
top->next=head[from];
head[from]=top++;
}

[LOJ 2133][UOJ 131][BZOJ 4199][NOI 2015]品酒大会的更多相关文章

  1. bzoj 4199 && NOI 2015 品酒大会

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

  2. [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机

    [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机 题意 给定平面上的 \(n\) 个整点 \((x_i,y_i)\), 一共有两个问题. 第一个问题是从原 ...

  3. [LOJ 2718][UOJ 393][BZOJ 5415][NOI 2018]归程

    [LOJ 2718][UOJ 393][BZOJ 5415][NOI 2018]归程 题意 给定一张无向图, 每条边有一个距离和一个高度. 再给定 \(q\) 组可能在线的询问, 每组询问给定一个点 ...

  4. [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分

    [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分 题意 给定一个字符串 \(S\), 求有多少种将 \(S\) 的子串拆分为形如 AABB 的拆分方案 \(| ...

  5. [LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士

    [LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士 题意 题面好啰嗦啊直接粘LOJ题面好了 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照 ...

  6. UOJ #131 BZOJ 4199 luogu P2178【NOI2015】品酒大会 (后缀自动机、树形DP)

    水是水,但是写出了不少问题,因此写一发博客. https://www.luogu.org/problemnew/show/P2178 https://www.lydsy.com/JudgeOnline ...

  7. 【UOJ #131】【NOI 2015】品酒大会

    http://uoj.ac/problem/131 求出后缀数组和height数组后,从大到小扫相似度进行合并,每次相当于合并两个紧挨着的区间. 合并区间可以用并查集来实现,每个区间的信息都记录在这个 ...

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

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

  9. [NOI 2015]品酒大会

    Description 题库链接 \(n\) 杯鸡尾酒排成一行,其中第 \(i\) 杯酒 (\(1 \leq i \leq n\)) 被贴上了一个标签 \(s_i\),每个标签都是 \(26\) 个小 ...

随机推荐

  1. Codeforces Round #603 (Div. 2) C. Everyone is a Winner! 二分

    C. Everyone is a Winner! On the well-known testing system MathForces, a draw of n rating units is ar ...

  2. Hbase内存磁盘大致关系

    转自: https://blog.csdn.net/wuwenxiang91322/article/details/51595771 Hbase内存磁盘关系磁盘数 diskNum磁盘容量 diskCa ...

  3. 持续集成(CI):WEB自动化+Allure+Jenkins定时构建

    一.allure插件安装 pytest可以通过allure集成展示优美的测试报告,同样allure也可以与Jenkins集成,并且Jenkins有构建记录,所以可以看到历史构建曲线图,通过曲线图可以清 ...

  4. Four Ways to Read Configuration Setting in C#(COPY)

    Introduction This article will demonstrate us how we can get/read the configuration setting from Web ...

  5. java基础(32):类加载、反射

    1. 类加载器 1.1 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 加载 就是指将class文件读入内存,并为之创建一个C ...

  6. 易优CMS:关于assign你知道多少

    [基础用法] 名称:assign 功能:模板文件中定义变量,可在其他标签里使用该变量 语法: {eyou:assign name='typeid' value='5' /} 文件: 无 参数: nam ...

  7. Java性能之优化RPC网络通信

    服务框架的核心 大型服务框架的核心:RPC通信 微服务的核心是远程通信和服务治理 远程通信提供了服务之间通信的桥梁,服务治理提供了服务的后勤保障 服务的拆分增加了通信的成本,因此远程通信很容易成为系统 ...

  8. C# virtual 和 abstract 区别

    Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例 ...

  9. 如何通过纯javascript实现表单提交

    通常,如果是POST方法,一般使用vuejs+axios,或使用Jquery实现表单提交.有些地方,我想使用纯JS实现,比方简单的登陆跳转.话不多说,看原代码, laravel中的HTML部分,如果不 ...

  10. laravel Error 笔记

    一.有关CSRF验证 1.网址访问POST请求,如 127.0.0.1:81/delUser?id=1  网页请求是默认是GET请求方式,看返回的数据信息就知道,数据是以GET方式发送的,所以若路由中 ...