hdu-5442(后缀数组,2015网络赛长春赛区)
2015-09-15 15:13
465 查看
题目链接
题意:给一个字符串,可以将其旋转,求旋转后的正或反方向字典序最大,如abca 正方向最大为 caba,反方向最大为cbaa,所以最大为cbaa。对于结果下标越小越好,相同下标优先选正方向。
思路:后缀自动机,对于正向,将串复制为两倍,用后缀数组得出最大后缀位置即可;对于反向,先将串翻转再x2,然后通过后缀数组得出的最大后缀位置为下标最大的字典序最大串,然后通过height数组>=len求出下标最小位置。
题意:给一个字符串,可以将其旋转,求旋转后的正或反方向字典序最大,如abca 正方向最大为 caba,反方向最大为cbaa,所以最大为cbaa。对于结果下标越小越好,相同下标优先选正方向。
思路:后缀自动机,对于正向,将串复制为两倍,用后缀数组得出最大后缀位置即可;对于反向,先将串翻转再x2,然后通过后缀数组得出的最大后缀位置为下标最大的字典序最大串,然后通过height数组>=len求出下标最小位置。
#pragma comment(linker,"/STACK:1024000000,1024000000") #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int maxn=60010; int t1[maxn],t2[maxn],c[maxn]; bool cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(int str[],int sa[],int rankk[],int height[],int n,int m){ n++; int i,j,p,*x=t1,*y=t2; for(int i=0;i<m;i++) c[i]=0; for(int i=0;i<n;i++) c[x[i]=str[i]]++; for(int i=1;i<m;i++) c[i]+=c[i-1]; for(int i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for(int j=1;j<=n;j<<=1){ p=0; for(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<m;i++) c[i]=0; for(i=0;i<n;i++) c[x[y[i]]]++; for(i=1;i<m;i++) c[i]+=c[i-1]; for(i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1;x[sa[0]]=0; for(i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; if(p>=n) break; m=p; } int k=0; n--; for(i=0;i<=n;i++) rankk[sa[i]]=i; for(i=0;i<n;i++){ if(k) k--; j=sa[rankk[i]-1]; while(str[i+k]==str[j+k]) k++; height[rankk[i]]=k; } } int rankk[maxn],height[maxn]; char str[maxn]; int r[maxn],sa[maxn]; int main() { int t,len; cin>>t; while(t--){ //rd(len); cin>>len; scanf("%s",str); for(int i=0;i<len;i++) r[i]=str[i]-'a'+1; for(int i=0;i<len;i++) r[i+len]=r[i]; r[len*2]=0; da(r,sa,rankk,height,len*2,27); string s1=""; int ans1=sa[len*2]; for(int i=0;i<len;i++) s1+=r[i+ans1]+'a'-1;//正向最大 if(ans1==0) { printf("%d %d\n",1,0); continue; } for(int i=0,j=len*2-1;i<j;i++,j--){ int tt=r[i];r[i]=r[j];r[j]=tt; } r[len*2]=0; da(r,sa,rankk,height,len*2,27); string s2=""; int ans2=sa[len*2]; for(int i=0;i<len;i++) s2+=r[i+ans2]+'a'-1;//反向最大 for(int i=2*len;i>1;i--){ if(sa[i-1]>=len) break; if(height[i]>=len) ans2=sa[i-1];//求反向最大最小下标 } ans2=len-1-ans2; // cout<<ans1<<" "<<ans2<<endl; // cout<<s1<<endl; // cout<<s2<<endl; ans2++;ans1++; if(s1==s2){ if(ans1>ans2) printf("%d %d\n",ans2,1); else printf("%d %d\n",ans1,0); } else if(s1>s2) printf("%d %d\n",ans1,0); else printf("%d %d\n",ans2,1); } return 0; }
相关文章推荐
- IOS AFNetworking https
- httpclient传参调用服务端方法
- HTTP File Server SoftWare
- HTTPConnection与HTTPClient的区别
- http协议与web本质
- swoole swoole_http yaf medoo 微信
- HTTP协议和web工作原理
- http
- 浅谈HttpClient
- Android之从网络上获取图片的两种方式讲解:thread+handle和AsyncTask方式
- (1)fcntl函数说明 F_SETLK/F_SETLKW例子 http://www.jb51.net/article/37671.htm
- java 请求http
- 理解HTTP幂等性
- linux性能监控以及网络命令
- 【网络通信:Volley】请求的发送与响应之JSON
- HTTP Client
- fcntl与文件锁 2013-11-25 15:45:55 http://blog.chinaunix.net/uid-20775448-id-4009263.html
- 浅论Android网络请求库——android-async-http(比较好的开源框架)
- HDU5032 -- Always Cook Mushroom 树状数组 14年北京网络赛
- epoll系列系统调用