【HDU4552】 怪盗基德的挑战书(后缀数组)
怪盗基德的挑战书
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 InputaaaababSample Output6
6
用后缀数组求的话,就是求出每个后缀和最长的后缀的公共前缀长度就可以了。
就是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】 怪盗基德的挑战书(后缀数组)的更多相关文章
- HDU - 4552 怪盗基德的挑战书 (后缀数组)
Description "在树最漂亮的那天,当时间老人再次把大钟平均分开时,我会降临在灯火之城的金字塔前.带走那最珍贵的笑容."这是怪盗基德盗取巴黎卢浮宫的<蒙娜丽莎的微笑& ...
- 后缀数组的倍增算法(Prefix Doubling)
后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1383 Solved: 582[Submit][St ...
- POJ3693 Maximum repetition substring [后缀数组 ST表]
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ...
- POJ1743 Musical Theme [后缀数组]
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ...
- 后缀数组(suffix array)详解
写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...
- 【UOJ #35】后缀排序 后缀数组模板
http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ...
- 【BZOJ-2119】股市的预测 后缀数组
2119: 股市的预测 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 334 Solved: 154[Submit][Status][Discuss ...
随机推荐
- pcap文件格式
pcap文件格式 pcap文件格式是bpf保存原始数据包的格式,很多软件都在使用,比如tcpdump.wireshark等等,了解pcap格式可以加深对原始数据包的了解,自己也可以手工构造任意的数 ...
- Python教程:操作数据库,MySql的安装详解
各位志同道合的同仁请点击上方关注 本教程是基于Python语言的深入学习.本次主要介绍MySql数据库软件的安装.不限制语言语法,对MySql数据库安装有疑惑的各位同仁都可以查看一下. 如想查看学习P ...
- jQuery模拟页面加载进度条
因为我们无法通过任何方法获取整个页面的大小和当前加载了多少,所以想制作一个加载进度条的唯一办法就是模拟.那要怎么模拟呢? 我们知道,页面是从上往下执行的,也就是说我们可以大致估算出在页面的某个位置加载 ...
- 多维数组遍历PHP
原文出处 <?php /* * ------------------------------------------------- * Author : nowamagic * Url : ww ...
- 深入理解自定义ListView
深入理解自定义ListView ListView原理 他是一个系统的原生控件,用列表的形式来显示内容.如果内容过过有1000条左右,我们可以通过手势的上下滑动来查看数据.ListView也不是爆出OO ...
- 个人博客设计:创建Sql数据库操作类。
整体的博客框架如下 数据库操作java类如下 package com.yxq.dao; import java.sql.Connection; import java.sql.DriverManage ...
- 什么是WordPress?
(今天由于好友 肖知虎的 的需求 , 我开始了帮助小虎建站的需求, 就这样开始学习了Wordpress. 这些文章就是为了记录这些我在学习过程当中的心得,和记录下来的文字而已) 什么是WordPre ...
- java中获得IP地址
public class IPTest { public static void main(String[] args) { try{ // 获取计算机名 String name = InetAddr ...
- Javascript基础学习(2)_表达式和运算符
1.==和===的区别(!=和!==是相反的比较) 它们采用了同一性的两个不同定义.==是相等性,===是等同性. ①“===”进行两个值的比较 两个值的类型不同,就不相等 两个值是数字,并且值相同, ...
- C#调用ActiveX控件
背景:最近项目中需要用到ActiveX控件,项目是在.Net平台下开发的.因此就直接在项目中添加了对ActiveX控件的引用,添加引用成功.在代码中实例化类的实例也没有问题,但在调用其方法或属性时总是 ...