[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 ...
随机推荐
- 第六节:SignalR完结篇之依赖注入和分布式部署
一. SignalR中DI思想的应用 DI,即依赖注入,它是一种不负责创建其自己的依赖项对象的一种模式,通常用来降低代码之间的耦合性,广泛应用于架构设计,是必不可少的一种思想. 下面结合一个需求来说一 ...
- Centos7 安装 scrapy
Centos7 安装 scrapy ( *:此python版本为 2.7 ) 1.先安装 python (2.7) 在安装 scrapy 要先安装 python 和 pip, 链接:https:// ...
- C语言官网蓝桥杯训练1115DNA
这道题是比较简单的输出字符图形的题,但是有几个坑还是要注意下. 1.题中所述的X是大写的,不要看成小写了.(我就错了好几次) 2.每一行输出最后的X后不能在输出空格. 3.输出两个DNA中间有一个空行 ...
- C#基础零碎知识点摘录
1.类分为静态类个非静态类(实例类) 静态类不能创建对象,使用方法时,直接类名.方法名(),常用的静态类有Console类 实例类:创建对象时通过对象调用类的方法 2.当我们声明一个类成员为静态时,意 ...
- RTF文件格式
文档地址 首先给出一个生成最简单的RTF文件的脚本 f=open('hello_world.rtf','w') padding='{\\rtf1\\ansi' padding+=' Hello Wor ...
- LNMP环境搭建:Nginx安装、测试与域名配置
Nginx作为一款优秀的Web Server软件同时也是一款优秀的负载均衡或前端反向代理.缓存服务软件 2.编译安装Nginx (1)安装Nginx依赖函数库pcre pcre为“perl兼容正则表达 ...
- vue——loading组件
<template> <div class="loading" :style="{height:loadingRadiusVal+'px',width: ...
- springboot配置Druid数据源
springboot配置druid数据源 Author:SimpleWu springboot整合篇 前言 对于数据访问层,无论是Sql还是NoSql,SpringBoot默认采用整合SpringDa ...
- php 的文件操作类
<?php header('Content-type:text/html;charset=utf8'); Class FILE { private static $path; private s ...
- Windows Internals 笔记——终止进程
1.进程可以通过以下四种方式终止: 主线程的入口点函数返回(强烈推荐的方式) 进程中的一个线程调用ExitProcess函数(避免这种方式) 另一个进程中的线程调用TerminateProcess函数 ...