【题目描述】

其实在开考前半个小时题面并不是这样的。

由于明天要考试,同学们要把抽屉里的书都搬空,书很多而且办了走读不能回寝室的学长一眼就看到了回班撩他的学姐,于是就把学姐当学长用♂了:“帮我把这摞书搬走OvO”。

学姐筋疲力尽地抱着沉重的一摞书回到了机房,出于无聊她翻开了学长的字典。

学长的字典由一个字符串组成。对于两个字符串a和b,如果a既是b的前缀也是b的后缀,那么称a和b“相似”,空字符串和任何字符串相似。一个字符串可以通过编辑变换成一个比它短而且与它相似的字符串,付出的代价为这两个字符串的长度之差的平方。两个字符串通过编辑而变为同一个字符串所花费的最小代价被称为最短编辑距离。

给定学长的字典,现在学姐想知道这个字符串的每一对前缀的最短编辑距离中的最大值是多少。请你帮助劳累的紫萱学姐解决这个问题。

【输入格式】

一个字符串,仅包含小写英文字母。

【输出格式】

这个字符串每一对前缀中最长的最短编辑距离。

【样例输入】

abcab

【样例输出】

23

【提示】

最短编辑距离最长的一对前缀是abca和abcab,最短变换过程如下(箭头中的数字为过程的代价)

“abca”-9->“a”-1->(空字符串)

“abcab”-9->“ab”-4->“”

对于40%的数据,n≤500。

对于70%的数据,n≤5000。

对于100%的数据,n≤1000000,n为字符串长度。

题解:

  不得不承认,这是一道非常好的题目,首先,我们可以考虑用哈希预处理出所以可能的转移,但这个题目可以贪心的思考,对于每个可能的相似前缀,只要考虑向最大的相似前缀转移就可以了。理由如下:

  1.对于一个前缀转移到一个更小的相似前缀,肯定是每次转移长度之差越小越好,因为a^2+b^2<x^2(x=a+b),所以我们每次转移的最大可转移的相似前缀上一定花费最小。

  2.对于前缀x的多种转移中次大的转移一定可以由最大的转移 转移过来,如一个len=7的前缀,可以转移到长度为5,长度为3,长度为0,这三种前缀上,那么5必定可以转移到3,3必定可以转移到0.

  所以我们只要对考虑最大的前缀就可以了(用类似于next数组的求发求)。

  如果我们把每个前缀看成一个节点(编号为前缀长度),然后向可转移的节点连边,边权为长度差,那么显然答案就变成了求任意两点到另一点的最短路之和,不难发现,连出来的边是一棵树,因为每个节点只会向前面的节点连边,并且对于每条链都会最后连到0节点。然后我们发现不用枚举所有的前缀作为两个前缀变成的相似前缀,因为就是我们所选两个节点的lca,这个十分显然因为边权是>0的,那么我们把边变成双向,就转化成了树上求直径问题了。

代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define MAXN 1000100
#define ll long long
using namespace std;
struct edge{
int first;
int next;
int to;
ll quan;
}a[MAXN*];
int f[MAXN],roof=,n;
ll dis[MAXN],dis2[MAXN],num=;
char s[MAXN]; void pre(){
f[]=;
for(int i=;i<=n;i++){
int j=f[i-];
while(j&&s[i]!=s[j+]) j=f[j];
if(s[i]==s[j+]) f[i]=j+;
else f[i]=j;
}
} void addedge(int from,int to,ll quan){
a[++num].to=to;
a[num].quan=quan;
a[num].next=a[from].first;
a[from].first=num;
} void dfs(int now,int fa,ll *dis){
for(int i=a[now].first;i;i=a[i].next){
ll to=a[i].to,quan=a[i].quan;
if(to==fa) continue;
dis[to]=dis[now]+quan;
dfs(to,now,dis);
}
} int main()
{
scanf("%s",s+);
n=strlen(s+);
pre();
for(int i=;i<=n;i++){
addedge(i,f[i],(long long)(i-f[i])*(i-f[i]));
addedge(f[i],i,(long long)(i-f[i])*(i-f[i]));
}
dfs(,,dis);
for(int i=;i<=n;i++) if(dis[roof]<dis[i]) roof=i;
memset(dis,,sizeof(dis));
dfs(roof,roof,dis2);
for(int i=;i<=n;i++) if(dis2[roof]<dis2[i]) roof=i;
printf("%lld",dis2[roof]);
return ;
}

COGS 2510. 拯救紫萱学姐的更多相关文章

  1. cdoj 1328 卿学姐与诡异村庄 Label:并查集 || 二分图染色

    卿学姐与诡异村庄 Time Limit: 4500/1500MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  ...

  2. Vijos1901 学姐的钱包

    描述 学姐每次出门逛街都要带恰好M元钱, 不过她今天却忘记带钱包了.可怜的doc只好自己凑钱给学姐, 但是他口袋里只有一元钱.好在doc的N位朋友们都特别有钱, 他们答应与doc作一些交换.其中第i位 ...

  3. cdoj 1329 卿学姐与魔法 优先队列

    卿学姐与魔法 Time Limit: 1200/800MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  4. cdoj 1324 卿学姐与公主 线段树裸题

    卿学姐与公主 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  5. vijosP1903学姐的实习工资

    描述 学姐去实习了, 一共实习了N天, 每一天都可以得到实习工资V[i], 这里V[1..N]被看作是整数序列.因为学姐很厉害, 所以V[1..N]是不下降的.也就是说学姐每天的工资只会越来越多, 不 ...

  6. vijos1891 学姐的逛街计划(线性规划)

    P1891学姐的逛街计划 描述 doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课.偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, 因为他还要陪 ...

  7. 2014.11.12模拟赛【美妙的数字】| vijos1904学姐的幸运数字

    美妙的数字(number.c/.cpp/.pas) 题目描述 黄巨大认为非负整数是美妙的,并且它的数值越小就越美妙.当然0是最美妙的啦. 现在他得到一串非负整数,对于每个数都可以选择先对它做二进制非运 ...

  8. UESTC - 1324 卿学姐与公主

    题目链接 某日,百无聊赖的卿学姐打开了某11区的某魔幻游戏 在这个魔幻的游戏里,生活着一个美丽的公主,但现在公主被关押在了魔王的城堡中. 英勇的卿学姐拔出利刃冲向了拯救公主的道路. 走过了荒野,翻越了 ...

  9. ATP学姐的模拟赛

    ATPの水题大赛 声明:不是我觉得这题水,这就是本场模拟赛的名称. T1:求所有的$n$位数中有几个数满足:每一位要么是$A$要么是$B$,并且这个$n$位数的每一位加起来是$A$或$B$的倍数. $ ...

随机推荐

  1. #umn 来美国近一个月的简单见闻

    时光如梭,到美国已经快要一个月了,从最初12+4飞行的劳累,到一开始每天吃了上顿没下顿的担心,到后来开始上课的不适,现如今生活已经基本步入了正轨,每天上上课写写作业,去rec center打打球健健身 ...

  2. ECharts使用总结归纳

    UserNAME:你为什么写这篇文章? My:最近项目中有统计报表的需求,使用了ECharts,“度娘”过程中东查西找太麻烦,自己写一篇加深印象,方便以后查阅. 辅助文档------>ttps: ...

  3. CSS——设置背景

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. HashMap源码分析(史上最详细的源码分析)

    HashMap简介 HashMap是开发中使用频率最高的用于映射(键值对 key value)处理的数据结构,我们经常把hashMap数据结构叫做散列链表: ObjectI entry<Key, ...

  5. 【Jenkins持续集成(一)】SonarQube 入门安装使用教程

    一.前言 持续集成管理平台不只是CI服务器,是一系列软件开发管理工具的组合. 源码版本管理:svn.git 项目构建工具:Maven.Ant 代码质量管理:Sonar(Checkstyle.PMD.F ...

  6. 《Java并发编程的艺术》读书笔记

    一.并发编程的挑战 上下文切换:cpu通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务.但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的 ...

  7. [STL] Implement "vector", ”deque“ and "list"

    vector “可增的”数组 vector是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似. 不同的地方就是: (1) 数组是静态分配空间,一旦分配了空间的大小,就不可再改变了: (2) v ...

  8. 使用mkfs.ext4格式化大容量磁盘

    使用mkfs.ext4默认参数格式化磁盘后,发现格式化时间特别长,并且格式化会占用磁盘很大的空间.例如2TB的磁盘格式化会占用10分钟左右时间,并占用30G左右的磁盘空间.究其原因,原来inode会占 ...

  9. 记一次java-selenium自动抢红包最简单案例1

    案例网址:http://xinyue.qq.com/act/pc/xyjf/a20170907envelopes/index.htm?ADTAG=AD_gw.home.pt.2_dyghb.20170 ...

  10. Dubbo源码解析(一)服务发现

    一.Dubbo源码模块 官网地址 源码地址 1.1 源码模块组织 Dubbo工程是一个Maven多Module的项目,以包结构来组织各个模块. 核心模块及其关系,如图所示: 1.2 模块说明 dubb ...