题目链接

思路 想到了,但是木写对啊....代码 各种bug,写的乱死了....

输出最靠前的,比较折腾...

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
#define N 501000
#define LL __int64
int sa[N],height[N],rank[N];
int c[N],wa[N],wb[N];
int p[N];
int res[N];
char str[N];
LL sum[N];
LL l,r;
int bin[];
int minz[][N];
int sz[][N];
void build_sa(int s[],int n,int m)
{
int i,j,p,*x = wa,*y = wb;
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(j = ;j <= n;j <<= )
{
p = ;
for(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 < 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];
swap(x,y);
p = ;x[sa[]] = ;
for(i = ;i < n;i ++)
x[sa[i]] = y[sa[i-]] == y[sa[i]]&&y[sa[i-]+j] == y[sa[i]+j]?p-:p++;
if(p >= n) break;
m = p;
}
}
void get_height(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 init(int n)
{
int i,j;
for(i = ; i <= n; i ++)
{
minz[][i] = height[i];
sz[][i] = sa[i];
}
for(i = ; bin[i] <= n; i ++)
{
for(j = ; j + bin[i-] <= n; j ++)
{
minz[i][j] = min(minz[i-][j],minz[i-][j+bin[i-]]);
sz[i][j] = min(sz[i-][j],sz[i-][j+bin[i-]]);
}
}
}
int rmq(int s,int t)
{
s = rank[s];
t = rank[t];
if(s > t) swap(s,t);
s ++;
int k = log((t-s+)*1.0)/log(2.0);
return min(minz[k][s],minz[k][t-bin[k]+]);
}
int rmq1(int s,int t)
{
s = rank[s];
t = rank[t];
if(s > t) swap(s,t);
s ++;
int k = log((t-s+)*1.0)/log(2.0);
return min(sz[k][s],sz[k][t-bin[k]+]);
}
void find(LL k,int n)
{
int str,end,mid,i;
str = ;
end = n;
while(str < end)
{
mid = (str + end + )/;
if(sum[mid] > k)
end = mid - ;
else
str = mid;
}
i = end;
if(sum[end] > k)
{
l = sa[i];
r = sa[i]+k-;
}
else if(k == sum[end])
{
l = sa[i];
r = n-;
}
else
{
i ++;
l = sa[i];
r = sa[i] + k - sum[end] + height[i]-;
}
int len = r-l+;
if(i == n)
{
l ++;
r ++;
return ;
}
if(height[i+] < len)
{
l ++;
r ++;
return ;
}
str = i+;
end = n;
while(str < end)
{
mid = (str + end + )/;
if(rmq(sa[i],sa[mid]) < len)
end = mid - ;
else
str = mid;
}
if(rmq(sa[i],sa[end]) >= len)
{
l = min(l,(LL)rmq1(sa[i],sa[end]));
r = l+len-;
}
l ++;
r ++;
}
int main()
{
int i,len,n;
LL maxz;
for(i = ; i < ; i ++)
bin[i] = <<i;
LL v,k;
while(scanf("%s",str)!=EOF)
{
len = strlen(str);
for(i = ;i < len;i ++)
{
p[i] = str[i]-'a'+;
}
p[len] = ;
build_sa(p,len+,);
get_height(p,len);
init(len);
maxz = ;
for(i = ;i <= len;i ++)
{
maxz += len-sa[i]-height[i];
sum[i] = maxz;
}
scanf("%d",&n);
l = r = ;
for(i = ;i < n;i ++)
{
scanf("%I64d",&v);
// find(v,len);
// printf("%I64d %I64d\n",l,r);
k = (v^l^r)+; if(k > maxz)
{
l = r = ;
}
else
{
find(k,len);
}
printf("%I64d %I64d\n",l,r);
}
}
return ;
}

HDU 5008 Boring String Problem(后缀数组+二分)的更多相关文章

  1. HDU - 5008 Boring String Problem (后缀数组+二分法+RMQ)

    Problem Description In this problem, you are given a string s and q queries. For each query, you sho ...

  2. HDU 5008 Boring String Problem

    题意:给定一个串长度<=1e5,将其所有的不同的字串按照字典序排序,然后q个询问,每次询问字典序第k小的的起始坐标,并且起始坐标尽量小. 分析: 一开始看错题意,没有意识到是求不同的字串中第k小 ...

  3. HDU5008 Boring String Problem(后缀数组)

    练习一下字符串,做一下这道题. 首先是关于一个字符串有多少不同子串的问题,串由小到大排起序来应该是按照sa[i]的顺序排出来的产生的. 好像abbacd,排序出来的后缀是这样的 1---abbacd ...

  4. HDOJ 5008 Boring String Problem

    后缀数组+RMQ+二分 后缀数组二分确定第K不同子串的位置 , 二分LCP确定可选的区间范围 , RMQ求范围内最小的sa Boring String Problem Time Limit: 6000 ...

  5. HDU 3518 Boring counting(后缀数组,字符处理)

    题目 参考自:http://blog.sina.com.cn/s/blog_64675f540100k9el.html 题目描述: 找出一个字符串中至少重复出现两次的字串的个数(重复出现时不能重叠). ...

  6. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

  7. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  8. BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )

    二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...

  9. 【bzoj4310】跳蚤 后缀数组+二分

    题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...

随机推荐

  1. 转载请注明出处: https://github.com/qiu-deqing/FE-interview

    转载请注明出处: https://github.com/qiu-deqing/FE-interview Table of Contents generated with DocToc FE-inter ...

  2. crontab详解

    搜索 纠正错误  添加实例 crontab 提交和管理用户的需要周期性执行的任务 补充说明 crontab命令 被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成 ...

  3. collections 模块(namedtuple, deque, Counter )

    基本介绍 我们都知道,Python拥有一些内置的数据类型,比如str, int, list, tuple, dict等, collections模块在这些内置数据类型的基础上,提供了几个额外的数据类型 ...

  4. 用SQL SERVER取分组数据第一条:查出每个班级的成绩第一名

    create table test (id int, name ), score int, classname )); ,,'一班'); ,,'一班'); ,,'一班'); ,,'二班'); ,,'二 ...

  5. 算法练习_图的连通性问题(JAVA)

    一.问题 1.问题描述: 有n个点(1...n),输入整数对(8,9),表示8,9点之间存在相互的连接关系. 动态连通性问题--编写一段程序过滤掉所以无意义的整数对,即为在不破坏图连通性的前提下,以最 ...

  6. 第一章 简单工厂模式 及 UML中类图的表示方法

    写一个简单计算器程序时,可以写一个操作类,然后加.减.乘.除操作分别继承它,复写操作计算结果的方法.写一个简单工厂类,通过输入的操作符,使用操作类来new一个相应的操作类的子类对象.这样,工厂就实例化 ...

  7. 纯html页面之间传参

    //页面引入//传参方法,可解析url参数 (function($){ $.getUrlParam = function(name) { var reg = new RegExp("(^|& ...

  8. java项目上线过程

    关于如何将Javaweb上线,部署到公网,让全世界的人都可以访问的问题.小编将作出系列化,完整的流程介绍. 1.在myeclipse中开发好项目,打包成war格式,不会的同学参考以下 http://z ...

  9. mysql workbench连接不上远程数据库,xshell无法连接远程主机的问题

    1.先说xshell无法连接的问题 最近使用virtualbox装了个ubuntu-16.04,然后在win7上使用xshell连接,首先确认win7能ping通虚拟机ip.然后确认是否安装了open ...

  10. ModelMapper 中高级使用 java

    ModelMapper 是一个java对象自动映射的第三方架包,用起来很方便,配合阿里的frstjson可以极大简化后台代码. 但是ModelMapper 中文使用说明很少,官网http://mode ...