[Educational Round 5][Codeforces 616F. Expensive Strings]
这题调得我心疲力竭...Educational Round 5就过一段时间再发了_(:з」∠)_
先后找了三份AC代码对拍,结果有两份都会在某些数据上出点问题...这场的数据有点水啊_(:з」∠)_【然而卡掉本弱还是轻轻松松的】
题目大意:给出\(n\)个字符串\(t_i\)以及\(n\)个数\(c_i\),定义\(p_{s,i}\)为字符串\(s\)在\(t_i\)中出现的次数,\(f(s)=\sum_{i=1}^{n}c_i\cdot p_{s,i}\cdot |s|\),求\(f(s)\)的最大值
题解:考虑将\(n\)个字符串用互不相同的字符串连接起来,并求出新串的后缀数组。对于一段连续且合法(对任意i,有sa[i]对应的字符不为连接符)的区间\([l,r]\),其对应的答案就为\(min\left \{ height_i \right \}\cdot \sum c_j\),\(j\)为sa[i]所属原字符串的编号,对应所取的字符串就是这连续几个后缀的最长公共子串。因此若考虑暴力枚举所有的合法区间,会有下面的代码
for(int l=;l<=len_sum;l++)if(s[sa[l]-]>N)
for(int r=l;r<=len_sum;r++)if(s[sa[r]-]<N)break;else
{
LL k=;
int mi=N;
for(int i=l+;i<=r;i++)mi=min(mi,height[i]);
if(mi==)break;
if(mi==N)
{
mi=;
for(int i=sa[l]-;s[i]>N;i++)
mi++;
}
for(int i=l;i<=r;i++)k+=1ll*mi*c[belong[sa[i]-]];
ans=max(ans,k);
}
暴力
但是这样是显然会TLE的,所以需要进一步优化
考虑每一个height[i]的影响范围,即在该范围内,所有包含i的区间都以height[i]为最小值,此时原式的式子就为\(height_i\cdot \sum_{i=l}^{r}c_j\),这里\(l\),\(r\)表示的就是height[i]的影响范围,\(j\)依然为sa[i]所属原字符串的编号。预处理每个height[i]的影响范围以及\(c_j\)的前缀和就好了
#include<bits/stdc++.h>
using namespace std;
#define N 600001
#define LL long long
int wa[N+],wb[N+],wv[N+],Ws[N+];
int cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];}
void da(const int r[],int sa[],int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=; i<m; i++) Ws[i]=;
for(i=; i<n; i++) Ws[x[i]=r[i]]++;
for(i=; i<m; i++) Ws[i]+=Ws[i-];
for(i=n-; i>=; i--) sa[--Ws[x[i]]]=i;
for(j=,p=; p<n; j*=,m=p)
{
for(p=,i=n-j; i<n; i++) y[p++]=i;
for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=; i<n; i++) wv[i]=x[y[i]];
for(i=; i<m; i++) Ws[i]=;
for(i=; i<n; i++) Ws[wv[i]]++;
for(i=; i<m; i++) Ws[i]+=Ws[i-];
for(i=n-; i>=; i--) sa[--Ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=; i<n; i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
}
int sa[N],Rank[N],height[N];
void calheight(const int *r,int *sa,int n)
{
int i,j,k=;
for(i=; i<=n; i++) Rank[sa[i]]=i;
for(i=; i<n; height[Rank[i++]]=k)
for(k?k--:,j=sa[Rank[i]-]; r[i+k]==r[j+k]; k++);
for(int i=n;i>=;--i) ++sa[i],Rank[i]=Rank[i-];
}
char str[N];
LL ans,sum[N];
int n,c[N],s[N],leng[N],belong[N],_l[N],_r[N],len_sum;
void rua(int L,int R)
{
LL res=,x,le;
for(int i=L;i<=R;i++)
{
x=belong[sa[i]-];
le=leng[x]-sa[i]+;
if((i==R || height[i+]<le) && (i==L || height[i]<le))
res=max(res,1ll*le*c[x]);
}
for(int i=L;i<=R;i++)
res=max(res,1ll*height[i]*(sum[min(R,_r[i])]-sum[max(L,_l[i]-)-]));
ans=max(ans,res);
}
int main()
{
scanf("%d",&n);
scanf("%s",str);
int len=strlen(str);
for(int i=;i<len;i++)
belong[len_sum]=,s[len_sum++]=str[i]+N;
leng[]=len_sum;
for(int i=;i<=n;i++)
{
s[len_sum++]=i;
scanf("%s",str);
len=strlen(str);
for(int j=;j<len;j++)
belong[len_sum]=i,s[len_sum++]=str[j]+N;
leng[i]=len_sum;
}
da(s,sa,len_sum+,N+);
calheight(s,sa,len_sum);
for(int i=;i<=n;i++)
scanf("%d",&c[i]);
for(int i=;i<=len_sum;i++)
sum[i]=sum[i-]+c[belong[sa[i]-]];
_l[]=,_r[len_sum]=len_sum;
for(int i=;i<=len_sum;i++)
{
int _=i;
while(_> && height[i]<=height[_-])
_=_l[_-];
_l[i]=_;
}
for(int i=len_sum-;i>=;i--)
{
int _=i;
while(_<len_sum && height[i]<=height[_+])
_=_r[_+];
_r[i]=_;
}
for(int l=;l<=len_sum;l++)if(s[sa[l]-]>N)
{
int r=l;
while(r<=len_sum && s[sa[r]-]>N)r++;
rua(l,r-);
l=r;
}
printf("%I64d\n",ans);
}
[Educational Round 5][Codeforces 616F. Expensive Strings]的更多相关文章
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- [Educational Round 3][Codeforces 609F. Frogs and mosquitoes]
这题拖了快一周_(:з」∠)_就把这货单独拿出来溜溜吧~ 本文归属:Educational Codeforces Round 3 题目链接:609F - Frogs and mosquitoes 题目 ...
- [Codeforces Round #438][Codeforces 868D. Huge Strings]
题目链接:868D - Huge Strings 题目大意:有\(n\)个字符串,\(m\)次操作,每次操作把两个字符串拼在一起,并询问这个新串的价值.定义一个新串的价值\(k\)为:最大的\(k\) ...
- [Educational Round 17][Codeforces 762F. Tree nesting]
题目连接:678F - Lena and Queries 题目大意:给出两个树\(S,T\),问\(S\)中有多少连通子图与\(T\)同构.\(|S|\leq 1000,|T|\leq 12\) 题解 ...
- [Educational Round 13][Codeforces 678F. Lena and Queries]
题目连接:678F - Lena and Queries 题目大意:要求对一个点集实现二维点对的插入,删除,以及询问\(q\):求\(max(x\cdot q+y)\) 题解:对每个点集内的点\(P( ...
- [Educational Round 10][Codeforces 652F. Ants on a Circle]
题目连接:652F - Ants on a Circle 题目大意:\(n\)个蚂蚁在一个大小为\(m\)的圆上,每个蚂蚁有他的初始位置及初始面向,每个单位时间蚂蚁会朝着当前面向移动一个单位长度,在遇 ...
- [Educational Round 59][Codeforces 1107G. Vasya and Maximum Profit]
咸鱼了好久...出来冒个泡_(:з」∠)_ 题目连接:1107G - Vasya and Maximum Profit 题目大意:给出\(n,a\)以及长度为\(n\)的数组\(c_i\)和长度为\( ...
- Codeforces Educational Round 33 题解
题目链接 Codeforces Educational Round 33 Problem A 按照题目模拟,中间发现不对就直接输出NO. #include <bits/stdc++.h> ...
- Codeforces Educational Round 92 赛后解题报告(A-G)
Codeforces Educational Round 92 赛后解题报告 惨 huayucaiji 惨 A. LCM Problem 赛前:A题嘛,总归简单的咯 赛后:A题这种**题居然想了20m ...
随机推荐
- ORACLE升级PSU&OJVM注意的问题及遇到问题解决思路
[环境介绍] 系统环境:Solaris + Oracle 11R2 + OGG + 脚本定时任务统计信息收集 [背景描述] 基于集团的安全检查,需要对数据库版本进行漏洞扫描,漏洞扫描中存在RBDMS和 ...
- [再寄小读者之数学篇](2014-10-18 利用 Lagrange 中值定理求极限)
试求 $$\bex \vlm{n}n^2\sex{x^\frac{1}{n}-x^\frac{1}{n+1}},\quad x>0. \eex$$ 解答: $$\beex \bea \mbox{ ...
- CSS三种样式
CSS 指层叠样式表 (Cascading Style Sheets): 1 内联样式:无法复用,在元素style内写 ,很少使用: 2 内部样式:在head元素内style属性内写,此样式可以被当前 ...
- python学习01
1.python怎样运行? 1)打开运行窗口,输入python 2)打开运行窗口,直接输入 python + python代码 `python -c "print(1/6.878)&quo ...
- IIS--互联网信息服务
IIS--互联网信息服务 1.IIS是微软出品的一个服务器插件 2.IIS的功能:1)发布web网站 2)发布ftp站点 WEB服务器:1.监听TCP80端口 --- http://www.baidu ...
- 6-12 varchar和char 枚举类型enum 集合set
1 字符类型char和varchar #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的参 ...
- css 初始化样式
@charset "UTF-8"; /* reset */ html,body,div,h1,h2,h3,h4,h5,h6,p,dl,dt,dd,ol,ul,li,fieldset ...
- 十一Python之路,Day6 - 面向对象学习
本节内容: 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法. 引子 你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战& ...
- C语言判断水仙花数
水仙花数 水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI).自恋数.自幂数.阿姆斯壮数或阿姆斯特朗数( ...
- element el-tree 添加图标
1.指定渲染函数:render-content="renderContent" <el-tree ref="tree" :data="funct ...