HDU 5008 Boring String Problem(后缀数组+二分)
思路 想到了,但是木写对啊....代码 各种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(后缀数组+二分)的更多相关文章
- 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 ...
- HDU 5008 Boring String Problem
题意:给定一个串长度<=1e5,将其所有的不同的字串按照字典序排序,然后q个询问,每次询问字典序第k小的的起始坐标,并且起始坐标尽量小. 分析: 一开始看错题意,没有意识到是求不同的字串中第k小 ...
- HDU5008 Boring String Problem(后缀数组)
练习一下字符串,做一下这道题. 首先是关于一个字符串有多少不同子串的问题,串由小到大排起序来应该是按照sa[i]的顺序排出来的产生的. 好像abbacd,排序出来的后缀是这样的 1---abbacd ...
- HDOJ 5008 Boring String Problem
后缀数组+RMQ+二分 后缀数组二分确定第K不同子串的位置 , 二分LCP确定可选的区间范围 , RMQ求范围内最小的sa Boring String Problem Time Limit: 6000 ...
- HDU 3518 Boring counting(后缀数组,字符处理)
题目 参考自:http://blog.sina.com.cn/s/blog_64675f540100k9el.html 题目描述: 找出一个字符串中至少重复出现两次的字串的个数(重复出现时不能重叠). ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- Poj 1743 Musical Theme(后缀数组+二分答案)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...
- BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )
二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...
- 【bzoj4310】跳蚤 后缀数组+二分
题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...
随机推荐
- Activity系列讲解---返回结果的处理
设想一下:由当前Activity跳转到其它Activity,从其它Activity再返回到当前Activity时,如何获取其它Activity存放的数据?下面用一个例子讲解, 点击selsect按钮跳 ...
- 在Ubuntu 14.04安装和使用Docker
Docker是一个开源软件,它可以把一个Linux应用和它所依赖的一切(比如配置文件)都封装到一个容器.然而,Docker与虚拟机不同,它使用了沙箱机制,Docker容器不运行操作系统,它共享主机上的 ...
- MySql导出数据到csv
通过mysql客户端shell连接到服务器,选择使用的数据库,输入sql代码: select * from test_info into outfile '/tmp/test.csv' fields ...
- vmware下centos7桥接模式无法上网
前一段时间由于想给vm中的centos分配一个独立的IP,就将网络适配器的连接方式由NAT改为桥接,一切顺利. 今天再次开机,IP居然变成了192开头的局域网,并且ping不通外网,经过查找资料,解决 ...
- python笔记:windows 下安装 python lxml
原文:http://blog.csdn.net/zhaokuo719/article/details/8209496 windows 环境下安装 lxml python 1.首先保证你的python ...
- 如何配置pch文件
pre-Compile Header(预编译头文件) pre-Compile Header简称PCH,由编译器在建立工程时自动生成; 其中存放有工程中已经编译的部分代码; 在以后建立工程时不再重新编译 ...
- EditView 输入限制(软键盘限制)
众所周知EditView有个inputType 属性可以设置输入的类型. 如下设置,则只能输入数字: android:inputType="number" 但是有时候需要自定义输入 ...
- net-force.nl/programming writeup
从 wechall.net 到 net-force.nl 网站,发现网站的内容不错,里面也有不同类型的挑战题目:Javascript / Java Applets / Cryptography / E ...
- C++ 系列:虚函数
Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明. -- ...
- WiX Toolset 教程索引页
注意:虽然WiX Toolset功能强大,但其学习曲线相对较高.请慎重选择: 若没有足够时间.没心思搞的请绕行至inno setup.installshield.nisi.setupfactory.. ...