怪盗基德的挑战书

Problem Description
  “在树最美丽的那天,当时间老人再次把大钟平均分开时,我会降临在灯火之城的金字塔前,带走那最珍贵的笑容。”这是怪盗基德盗取巴黎卢浮宫的《蒙娜丽莎的微笑》这幅画时,挑战书上的内容。
  但这次,怪盗基德的挑战书上出现了一串串小写字母“aaab sdfeeddd...”。柯南以小学生的眼睛,超凡高中生的头脑,快速统计各种字母频率,字符串长度,并结合挑战书出现的时间等信息,试图分析怪盗基德的意图。最后,他将线索锁定在字符串的循环次数上。并且进一步推理发现,从字符串的第一位开始,到第i位,形成该字符串的子串(c1, c2, c3 ... ci )。对于某一子串ci在该字符串中出现的次数记为ki,则全部子串的循环次数总和AIM = k1 + k2 + ... + ki + ... + kn,柯南发现,AIM恰好对应一个ASCII码!所以,只要把挑战书上的字符串转变成数字,再找到对应的ASCII码,就可以破解这份挑战书了!
  现在,你的任务就是把字符串转变成对应数字,因为ASCII码以及扩展ASCII码全部只有256个,所以,本题只要把结果对256取余即可。
Input
输入有多组测试数据;
每组测试数据只有一个字符串,由各种小写字母组成,中间无空格。
字符串的长度为L(0 < L <= 100000)。
Output
请计算并输出字符串的AIM值,每组数据输出一行。
Sample Input
aaa
abab
 
Sample Output
6
6
 
 
【题意】
  给一个串s,求s的每个前缀出现次数之和。
 
【分析】

  用后缀数组求的话,就是求出每个后缀和最长的后缀的公共前缀长度就可以了。

  就是rank[1]的位置往两边找。

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 0xfffffff
#define Maxl 100010
#define Mod 256 int k,la;
char a[Maxl],b[Maxl];
int c[Maxl];
int cl; int sa[Maxl],rk[Maxl],Rs[Maxl],wr[Maxl],y[Maxl];
//sa -> 排名第几的是谁
//rk -> i的排名
//Rs数值小于等于i的有多少个
//y -> 第二关键字排名第几的是谁(类似sa)
int height[Maxl]; int mymin(int x,int y) {return x<y?x:y;} void get_sa(int m)
{
memcpy(rk,c,sizeof(rk));
for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[rk[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[rk[i]]--]=i; int ln=,p=;
while(p<cl)
{
int k=;
for(int i=cl-ln+;i<=cl;i++) y[++k]=i;
for(int i=;i<=cl;i++) if(sa[i]>ln) y[++k]=sa[i]-ln;
for(int i=;i<=cl;i++) wr[i]=rk[y[i]]; for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[wr[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[wr[i]]--]=y[i]; for(int i=;i<=cl;i++) wr[i]=rk[i];
for(int i=cl+;i<=cl+ln;i++) wr[i]=;
p=;rk[sa[]]=;
for(int i=;i<=cl;i++)
{
if(wr[sa[i]]!=wr[sa[i-]]||wr[sa[i]+ln]!=wr[sa[i-]+ln]) p++;
rk[sa[i]]=p;
}
m=p,ln*=;
}
sa[]=rk[]=;
} void get_he()
{
int kk=;
for(int i=;i<=cl;i++)
{
int j=sa[rk[i]-];
if(kk) kk--;
while(c[i+kk]==c[j+kk]&&i+kk<=cl&&j+kk<=cl) kk++;
height[rk[i]]=kk;
}
} void ffind()
{
int ans=,minn=INF;
ans+=cl;
for(int i=rk[];i>=;i--)
{
minn=mymin(minn,height[i]);
ans=(ans+minn)%Mod;
}minn=INF;
for(int i=rk[]+;i<=cl;i++)
{
minn=mymin(minn,height[i]);
ans=(ans+minn)%Mod;
}
printf("%d\n",ans);
} int main()
{
while(scanf("%s",a)!=EOF)
{
cl=strlen(a);
for(int i=;i<cl;i++) c[i+]=a[i]-'a'+;
get_sa();
get_he();
ffind();
}
return ;
}

[HDU4522]

2016-07-17 15:50:30

【HDU4552】 怪盗基德的挑战书(后缀数组)的更多相关文章

  1. HDU - 4552 怪盗基德的挑战书 (后缀数组)

    Description "在树最漂亮的那天,当时间老人再次把大钟平均分开时,我会降临在灯火之城的金字塔前.带走那最珍贵的笑容."这是怪盗基德盗取巴黎卢浮宫的<蒙娜丽莎的微笑& ...

  2. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  3. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  4. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  5. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  6. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  7. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

  8. 【UOJ #35】后缀排序 后缀数组模板

    http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ...

  9. 【BZOJ-2119】股市的预测 后缀数组

    2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 334  Solved: 154[Submit][Status][Discuss ...

随机推荐

  1. Java实现直接插入查找

    import java.util.Scanner; /*算法思想:每趟将一个待排序的元素作为关键字,按照关键字值大小插入到已排好序的那部分序列的适当位置上,直到插入完成,*/ /*平均时间复杂度O(n ...

  2. JS如何封装一些列方法为一个对象的操作,然后集中管理这些操作,方便修改和调用

    var Api = { ajax:{ // 添加项目 旧! add_project : function(pro_name, html, css, js,callback) { $.post(&quo ...

  3. 程序员带你十天快速入门Python,玩转电脑软件开发(四)

    本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结.本篇文章主要是基于上一篇的程序员带你十天快速入门Python,玩转电脑软件开发(三)的基础之上, ...

  4. C语言基础知识小总结(2)

    上个总结比较笼统,下面写的稍微详细点吧算是.   一.控制台屏幕打印 1.putchar();   格式: void putchar(char c);  //直接把一个字符输出到屏幕上 2.print ...

  5. Quarzt.NET的Cron表达式理解

    网上关于Quarzt.NET的Cron表达式介绍有很多,但都是基本的语法,稍微深入一些的就没有了. 基本语法介绍请参看: http://www.cnblogs.com/lzrabbit/archive ...

  6. C# DbHelperSQLP,操作不同的数据库帮助类 (转载)

    本类主要是用来访问不同数据库而编写的主要功能如下 .数据访问基础类(基于不同数据库),主要是用来访问不同数据库的. .得到最大值:是否存在:是否存在: . 执行SQL和Orace语句,返回影响的记录数 ...

  7. # Day04-Android

    Day04-Android 标签(空格分隔): andrroid 1.制作界面 2.在写Activity. Logcat LayoutInflate把Xml转换纯成View的工具. 自定义吐司 Lay ...

  8. 黑马入学基础测试(三)求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

    .获得用户的输入 计算      3打印就行了.   这里用到了java.util.Scanner   具体API  我就觉得不常用.解决问题就ok了.注意的是:他们按照流体的方式读取.而不是刻意反复 ...

  9. Javascript基础学习(2)_表达式和运算符

    1.==和===的区别(!=和!==是相反的比较) 它们采用了同一性的两个不同定义.==是相等性,===是等同性. ①“===”进行两个值的比较 两个值的类型不同,就不相等 两个值是数字,并且值相同, ...

  10. ios动力特效,最重要的一点 属性保持(写了动力特效但是没效果的原因就在这里)

    @property (nonatomic, strong) UIDynamicItemBehavior *square1PropertiesBehavior; @property (nonatomic ...