稍微学习了下第一次用后缀数组- - , 强行凑出答案 , 感觉现在最大的问题是很多算法都不知道 ,导致有的题一点头绪都没有(就像本题)。  /*推荐 《后缀数组——处理字符串的有力工具》——罗穗骞

后缀数组sa,  sa[ i ] = a表示字符串从第a个开始到结尾的字典序排序为i

本题是绕成了一个环,所以我将字符串重复一遍再用后缀数组模板跑一次。

顺序的话,取最后一个即可

反序的话,因为相同情况下,要求取得尽可能小。

hight求的是i和i-1的最长公共前缀,如果串i-1整个是公共最长前缀,即说明他们的字典序本该是一样的,只是在双倍的情况下i多算一部分,所以有先取i-1

//思路应该没问题,代码是在不停wa中莫名改出来的- -

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;const int maxn=200000+10;int wa[maxn],wb[maxn],wv[maxn],wss[maxn],rak[maxn];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int *r,int *sa,int n,int m)
{int i,j,p,*x=wa,*y=wb,*t;for(i=0; i<m; i++) wss[i]=0;for(i=0; i<n; i++) wss[x[i]=r[i]]++;for(i=1; i<m; i++) wss[i]+=wss[i-1];for(i=n-1; i>=0; i--) sa[--wss[x[i]]]=i;for(j=1,p=1; p<n; j*=2,m=p){for(p=0,i=n-j; i<n; i++) y[p++]=i;for(i=0; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;for(i=0; i<n; i++) wv[i]=x[y[i]];for(i=0; i<m; i++) wss[i]=0;for(i=0; i<n; i++) wss[wv[i]]++;for(i=1; i<m; i++) wss[i]+=wss[i-1];for(i=n-1; i>=0; i--) sa[--wss[wv[i]]]=y[i];for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1; i<n; i++)x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;}return ;
}char s[2*maxn],rev[2*maxn];
int sa[maxn],r[maxn],height[maxn];
int n;
int p0,p1;
void build_height(int n)
{int i,k=0;for(i=0; i<n; i++)rak[sa[i]]=i;for(i=0; i<n; i++){if(k)k--;int j=sa[rak[i]-1];while(s[i+k]==s[j+k])k++;height[rak[i]]=k;}
}void solve(int x)
{if(!x){int t = 0;memset(sa,0,sizeof(sa));for(int i = 0; i < n; i++)r[t++]=s[i]-'a'+1;r[t++] = 0;da(r,sa,t,30);p0 = sa[t-1]+1;}else{int t = 0;memset(sa,0,sizeof(sa));for(int i = 0; i < n; i++)r[t++]=rev[i]-'a'+1;r[t++] = 0;da(r,sa,t,30);build_height(t);int k = t-2;while(k>=4&&height[k]&&height[k]==n-sa[k-1])k--;p1 = sa[k];}
}int cmp(char*s,char*t,int p,int q)
{for(int i=0; i<n; i++)if(s[(p+i)%n]!=t[(q+i)%n])return s[(p+i)%n]>t[(q+i)%n];return 2;
}int main()
{int T;scanf("%d",&T);while(T--){scanf("%d",&n);scanf("%s",s);for(int i = 0; i < n; i++)s[n+i] = s[i];n = 2*n;for(int i=0; i<n; i++)rev[i]=s[n-1-i];solve(0);solve(1);int ans,dir;int tmp = p1;// printf("%d %d\n",p0,tmp);p1 = n-p1;n/=2;int d=cmp(s,rev,p0-1,tmp);//printf("%d %d\n",p0,tmp);if(d==2){if(p0<=p1)ans=p0,dir=0; else ans=p1,dir=1;}else if(d>0)ans=p0,dir=0;else ans=p1,dir=1;printf("%d %d\n",ans,dir);}return 0;
}

  

转载于:https://www.cnblogs.com/Przz/p/5409756.html

hdu 5442 (后缀数组)相关推荐

  1. hdu 2459 (后缀数组+RMQ)

    题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...

  2. hdu 6194 后缀数组

    题意:一个字符串,查询恰好出现k次的子串的数目 思路:后缀数组在height上进行操作.我们直接枚举长度为k的区间求min值,但是要注意的是直接这么算是会重复的,同时也可能超过k次,这样我们就需要把枚 ...

  3. HDU 6194 后缀数组+单调栈

    题意: 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6194 找到一个字符串中恰好出现k次的子串的数目. 思路: 计算出height数组,根据heig ...

  4. hdu 4416 后缀数组

    昨天做1007,做到吐血,一直wa,原来是结果是超int的,好容易算错啊,刚刚好觉得是10位,没超, 但是那是10位0,还有最高为1啊,又范这种低级错误了,引以为戒,不要在范. 先说一下我的做法,利用 ...

  5. hdu 3948(后缀数组+RMQ)

    题意:求一个串中有多少不同的回文串. 分析:这一题的关键是如何去重,我表示我现在还没理解为什么这样去重,先放这里过两天再看!! //不同回文子串数目 #include <iostream> ...

  6. hdu 5008 Boring String Problem(后缀数组+rmq)

    题目链接:hdu 5008 Boring String Problem 题意: 给你一个字符串,有q个询问,每次询问该字符串所有的子串中字典序第k小的是哪个串,输出位置,如果有多个位置,输出最靠左的那 ...

  7. 后缀数组 --- HDU 3518 Boring counting

    Boring counting Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3518 Mean: 给你一个字符串,求:至少出 ...

  8. HDU 6194 string string string :后缀数组+单调队列 | 后缀自动机

    题意:给出一个字符串,求出出现了恰好k次的子串的个数. 题解:恰好k次 = 至少k次 - 至少k+1次.答案转化为求至少出现k次的子串个数统计.构造好后缀数组以及很重要的Height数组之后.用一个k ...

  9. HDU 4416 Good Article Good sentence(12年杭州 后缀数组)

    转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:给出一个A串,给出若干个B ...

  10. Boring counting HDU - 3518 (后缀数组)

    Boring counting \[ Time Limit: 1000 ms \quad Memory Limit: 32768 kB \] 题意 给出一个字符串,求出其中出现两次及以上的子串个数,要 ...

最新文章

  1. Django快速分页
  2. 「镁客·请讲」必捷网络王振中:融合视联网平台将从根本上治疗实时通讯行业应用痛点...
  3. 按键精灵通过句柄获取窗口坐标_使用visual studio 2019 创建简单的Windows窗口「Win32」...
  4. Non-interger Area 分类讨论 奇偶 取模 牛客练习赛95
  5. 线性表的应用之多项式的表示与相加
  6. JQuery:deferred对象的方法
  7. matlab slider不可移动,GUI界面能运行,但是_slider不能用,不能控制波长
  8. ecshop使用php代码,ecshop 修改模板可输出php代码
  9. table表格表头不懂,内容y轴滚动
  10. 显示recv调用次数_腾讯云“云开发”日调用超7亿次,只为和开发者“交个朋友”...
  11. java u0002_老玩法,输出金字塔
  12. StringJoiner
  13. 计算机基础知识题库pdf,计算机基础知识题库完整.pdf
  14. java poi 合并单元格
  15. amd cpu排行_最新intel和amd处理器性能排行cpu天梯图2019
  16. 解析12306订票流程
  17. python选取tensor某一维_超简单!pytorch入门教程(一):Tensor
  18. 微信小程序开发语言的选择
  19. 考研复试c语言面试题三峡,2017年三峡大学C语言程序设计(复试)考研真题硕士研究生入学考试试题...
  20. 记一次gitbook的安装

热门文章

  1. com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient
  2. python卡方拟合性检验_卡方检验
  3. 取次花丛懒回顾,半缘修道半缘君。
  4. nodejs安装时遇到的问题及解决方案
  5. 查看网络连接的netstat命令
  6. Exploiting Cloze Questions for Few Shot Text Classification and Natural Language Inference
  7. 三峡大学校赛----十万桃花图(线性基)
  8. 议题曝光!百位顶级讲师、20大论坛,总有一个话题吸引你
  9. java多态、抽象类和接口
  10. java 用户拒绝对代码授予权限_java – @Secured函数获取授权用户的拒绝访问权限...