题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691

  后缀数组模板题,求出Height数组后,对Height做RMQ,然后直接统计就可以了。。。

 //STATUS:C++_AC_828MS_11284KB
#include <functional>
#include <algorithm>
#include <iostream>
//#include <ext/rope>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,102400000")
//using namespace __gnu_cxx;
//define
#define pii pair<int,int>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1.0)
//typedef
typedef __int64 LL;
typedef unsigned __int64 ULL;
//const
const int N=;
const int INF=0x3f3f3f3f;
const int MOD=,STA=;
const LL LNF=1LL<<;
const double EPS=1e-;
const double OO=1e15;
const int dx[]={-,,,};
const int dy[]={,,,-};
const int day[]={,,,,,,,,,,,,};
//Daily Use ...
inline int sign(double x){return (x>EPS)-(x<-EPS);}
template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
template<class T> inline T lcm(T a,T b,T d){return a/d*b;}
template<class T> inline T Min(T a,T b){return a<b?a:b;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
//End char s[N];
int d[N][];
int num[N];
int sa[N],t1[N],t2[N],c[N],rank[N],height[N];
int n,m; void build_sa(int s[],int n,int m)
{
int i,k,p,*x=t1,*y=t2;
//第一轮基数排序
for(i=;i<m;i++)c[i]=;
for(i=;i<n;i++)c[x[i]=s[i]]++;
for(i=;i<m;i++)c[i]+=c[i-];
for(i=n-;i>=;i--)sa[--c[x[i]]]=i;
for(k=;k<=n;k<<=){
p=;
//直接利用sa数组排序第二关键字
for(i=n-k;i<n;i++)y[p++]=i;
for(i=;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k;
//基数排序第一关键字
for(i=;i<m;i++)c[i]=;
for(i=;i<n;i++)c[x[y[i]]]++;
for(i=;i<m;i++)c[i]+=c[i-];
for(i=n-;i>=;i--)sa[--c[x[y[i]]]]=y[i];
//根据sa和x数组计算新的x数组
swap(x,y);
p=;x[sa[]]=;
for(i=;i<n;i++)
x[sa[i]]=y[sa[i-]]==y[sa[i]] && y[sa[i-]+k]==y[sa[i]+k]?p-:p++;
if(p>=n)break; //已经排好序,直接退出
m=p; //下次基数排序的最大值
}
} void getHeight(int s[],int n)
{
int i,j,k=;
for(i=;i<=n;i++)rank[sa[i]]=i;
for(i=;i<n;i++){
if(k)k--;
j=sa[rank[i]-];
while(s[i+k]==s[j+k])k++;
height[rank[i]]=k;
}
} void rmq_init(int a[])
{
int i,j;
for(i=;i<=n;i++)d[i][]=a[i];
for(j=;(<<j)<=n;j++){
for(i=;i+(<<j)-<=n;i++){
d[i][j]=Min(d[i][j-],d[i+(<<(j-))][j-]);
}
}
} int rmq(int l,int r)
{
int k=;
while((<<(k+))<=r-l+)k++;
return Min(d[l][k],d[r-(<<k)+][k]);
} int lcp(int a,int b)
{
if(a==b)return n-a; //a和b为同一后缀,直接输出,字串串长度为n
int ra=rank[a],rb=rank[b];
if(ra>rb)swap(ra,rb);
return rmq(ra+,rb);
} int w[N]; int main(){
// freopen("in.txt","r",stdin);
int i,j,k,Q,a,b,la,lb;
LL ans1,ans2,t;
w[]=;
for(i=k=;i<N;i=j,k++)
for(j=i*;i<j && i<N;i++)w[i]=k;
while(~scanf("%s",s))
{
n=strlen(s);
for(i=;i<n;i++)
num[i]=s[i]-'a'+;
num[n]=;m=;
build_sa(num,n+,m);
getHeight(num,n);
rmq_init(height); scanf("%d",&Q);
ans1=(LL)Q,ans2=(LL)*Q;
scanf("%d%d",&la,&lb);
ans1+=(LL)lb-la;ans2+=(LL)lb-la+;
while(--Q){
scanf("%d%d",&a,&b);
ans1+=(LL)b-a;
t=(LL)Min(lcp(la,a),lb-la,b-a);
ans2+=(LL)b-a-t+w[t];
// printf(" %I64d %d %d %d\n",t,lcp(la,a),lb-la,b-a);
la=a;lb=b;
} printf("%I64d %I64d\n",ans1,ans2); }
return ;
}

HDU-4691 Front compression 后缀数组的更多相关文章

  1. hdu 4691 Front compression (后缀数组)

    hdu 4691 Front compression 题意:很简单的,就是给一个字符串,然后给出n个区间,输出两个ans,一个是所有区间的长度和,另一个是区间i跟区间i-1的最长公共前缀的长度的数值的 ...

  2. HDU 4691 Front compression(后缀数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691 题意:给出Input,求出Compressed output.输出各用多少字节. 思路:求后缀数 ...

  3. HDU 4691 Front compression (2013多校9 1006题 后缀数组)

    Front compression Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Othe ...

  4. hdu4691 Front compression(后缀数组)

    Front compression Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) ...

  5. HDU 4691 正解后缀数组(暴力也能过)

    本来是个后缀数组,考察算法的中级题目,暴力居然也可以水过,就看你跳不跳坑了(c++和G++返回结果就很不一样,关键看编译器) 丝毫不差的代码,就看运气如何了.唯一差别c++还是G++,但正解是后缀数组 ...

  6. hdu 4691 Front compression

    暴力水过,剪一下枝= =果断是数据水了 #include<cstdio> #include<cstring> #include<algorithm> #define ...

  7. 【HDOJ】4691 Front compression

    后缀数组基础题目,dc3解. /* 4691 */ #include <iostream> #include <sstream> #include <string> ...

  8. hdu 5442 Favorite Donut 后缀数组

    Favorite Donut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid ...

  9. hdu 4622 Reincarnation(后缀数组)

    hdu 4622 Reincarnation 题意:还是比较容易理解,给出一个字符串,最长2000,q个询问,每次询问[l,r]区间内有多少个不同的字串. (为了与论文解释统一,这里解题思路里sa数组 ...

随机推荐

  1. c++调用matlab生成的Dll动态连接库

    点击打开链接http://download.csdn.net/detail/nuptboyzhb/4228429 c++调用matlab生成的Dll动态连接库 实验平台:   matlab 7.0(R ...

  2. SDUT 2527 斗地主

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2527 思路 :以前的结训比赛,当时不会做,比完 ...

  3. MySQL在windows和linux下的表名大小写问题

    MySQL在windows下是不区分大小写的,将script文件导入MySQL后表名也会自动转化为小写,结果再想要将数据库导出放到linux服务 器中使用时就出错了.因为在linux下表名区分大小写而 ...

  4. [itint5]两数积全为1

    http://www.itint5.com/oj/#18 这一题,首先如果直接去算的话,很容易就超出int或者long的表示范围了.那么要利用%的性质,(num * 10 + 1) % a = 10 ...

  5. Java中List的排序

    第一种方法,就是list中对象实现Comparable接口,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 2 ...

  6. ANDROID_MARS学习笔记_S01_004dpi、dp(dip)及计算

    一.dpi.dp介绍 sp会随着用户在手机中设置字体大小而改变,而dp不会 二.1.dpsp_layout.xml <?xml version="1.0" encoding= ...

  7. Android 开发之 ---- 底层驱动开发(一)

    驱动概述 说到 android 驱动是离不开 Linux 驱动的.Android 内核采用的是 Linux2.6 内核 (最近Linux 3.3 已经包含了一些 Android 代码).但 Andro ...

  8. Zookeeper命令

    常用命令 ZooKeeper 支持某些特定的四字命令字母与其的交互.它们大多是查询命令,用来获取 ZooKeeper 服务的当前状态及相关信息.用户在客户端可以通过 telnet 或 nc 向 Zoo ...

  9. java中synchronized的用法详解

    记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...

  10. poj 1125 Stockbroker Grapevine(最短路 简单 floyd)

    题目:http://poj.org/problem?id=1125 题意:给出一个社交网络,每个人有几个别人可以传播谣言,传播谣言需要时间.问要使得谣言传播的最快,应该从那个人开始传播谣言以及使得所有 ...