HDU 5442 Favorite Donut 后缀数组
2016-06-11 13:33
344 查看
题意:
给你一个甜甜圈,可以正着次也可以反着次求如何按照字典序最大次
后缀数组正反跑一跑就好了
ACcode:
#include <bits/stdc++.h>
#define maxn 20200
using namespace std;
int t1[maxn<<1],t2[maxn<<1],c[maxn<<1];
int r[maxn<<1],sa[maxn<<1],h[maxn<<1],str[maxn<<1];
inline bool cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
inline void da(int n,int m){
n++;
int *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){
int p=0;
for(int i=n-j;i<n;++i)y[p++]=i;
for(int i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
for(int i=0;i<m;++i)c[i]=0;
for(int i=0;i<n;++i)c[x[y[i]]]++;
for(int i=1;i<m;++i)c[i]+=c[i-1];
for(int i=n-1;i>=0;--i)sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1;
x[sa[0]]=0;
for(int 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(int i=0;i<=n;++i)r[sa[i]]=i;
for(int i=0;i<n;++i){
if(k)k--;
int j=sa[r[i]-1];
while(str[i+k]==str[j+k])k++;
h[r[i]]=k;
}
}
char s[maxn],s1[maxn<<1],s2[maxn<<1];
int pos1,pos2,loop,n;
void doit(){
string a="",b="";
for(int i=0;i<n;++i){
a+=s1[(pos1+i)%n];
b+=s2[(pos2+i)%n];
}
for(int i=2*n;i>1;i--){
if(sa[i-1]>=n) break;
if(h[i]>=n) pos2=sa[i-1];//求反向最大最小下标
}
pos2=n-1-pos2;
pos1++,pos2++;
if(a==b){
if(pos1>pos2) printf("%d 1\n",pos2);
else printf("%d 0\n",pos1);
}
else if(a>b) printf("%d 0\n",pos1);
else printf("%d 1\n",pos2);
}
int main(){
scanf("%d",&loop);
while(loop--){
scanf("%d",&n);
scanf("%s",s);
for(int i=0;i<n;++i)
str[i]=str[i+n]=s1[i]=s1[i+n]=s[i];
str[2*n]=0;
da(n*2,256);
pos1=sa[2*n];
for(int i=n*2-1,k=0;i>=0;--i,++k)
str[k]=s2[k]=s1[i];
da(n*2,256);
pos2=sa[2*n];
doit();
}
return 0;
}
给你一个甜甜圈,可以正着次也可以反着次求如何按照字典序最大次
后缀数组正反跑一跑就好了
ACcode:
#include <bits/stdc++.h>
#define maxn 20200
using namespace std;
int t1[maxn<<1],t2[maxn<<1],c[maxn<<1];
int r[maxn<<1],sa[maxn<<1],h[maxn<<1],str[maxn<<1];
inline bool cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
inline void da(int n,int m){
n++;
int *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){
int p=0;
for(int i=n-j;i<n;++i)y[p++]=i;
for(int i=0;i<n;++i)if(sa[i]>=j)y[p++]=sa[i]-j;
for(int i=0;i<m;++i)c[i]=0;
for(int i=0;i<n;++i)c[x[y[i]]]++;
for(int i=1;i<m;++i)c[i]+=c[i-1];
for(int i=n-1;i>=0;--i)sa[--c[x[y[i]]]]=y[i];
swap(x,y);
p=1;
x[sa[0]]=0;
for(int 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(int i=0;i<=n;++i)r[sa[i]]=i;
for(int i=0;i<n;++i){
if(k)k--;
int j=sa[r[i]-1];
while(str[i+k]==str[j+k])k++;
h[r[i]]=k;
}
}
char s[maxn],s1[maxn<<1],s2[maxn<<1];
int pos1,pos2,loop,n;
void doit(){
string a="",b="";
for(int i=0;i<n;++i){
a+=s1[(pos1+i)%n];
b+=s2[(pos2+i)%n];
}
for(int i=2*n;i>1;i--){
if(sa[i-1]>=n) break;
if(h[i]>=n) pos2=sa[i-1];//求反向最大最小下标
}
pos2=n-1-pos2;
pos1++,pos2++;
if(a==b){
if(pos1>pos2) printf("%d 1\n",pos2);
else printf("%d 0\n",pos1);
}
else if(a>b) printf("%d 0\n",pos1);
else printf("%d 1\n",pos2);
}
int main(){
scanf("%d",&loop);
while(loop--){
scanf("%d",&n);
scanf("%s",s);
for(int i=0;i<n;++i)
str[i]=str[i+n]=s1[i]=s1[i+n]=s[i];
str[2*n]=0;
da(n*2,256);
pos1=sa[2*n];
for(int i=n*2-1,k=0;i>=0;--i,++k)
str[k]=s2[k]=s1[i];
da(n*2,256);
pos2=sa[2*n];
doit();
}
return 0;
}
相关文章推荐
- Python连接mysql
- List和ArrayList的区别
- 数据库操作中 pstmt.setString(1,id) ; 是什么意思 那个“1”指什么?
- LINUX中驱动异步通知应用程序的方法
- 用Activity的onTouchEvent方法实现监听手指上下左右滑动
- R语言︱线性混合模型理论与案例探究(固定效应&随机效应)
- Remove Duplicates from Sorted List
- js获取客户端IP及地理位置
- 提高PHP代码执行效率小结
- HDU 5438 Ponds
- 开发故事中的各种小虫(持续更新)
- PAT 1050.螺旋矩阵(25)
- hadoop hdfs运行机制
- 命令模式
- 关于中值滤波算法,以及C语言实现
- Android视图的绘制流程(下)——View的Layout与Draw过程
- 【Dongle】【VS】之窗体异常
- 为什么手机不能既开WiFi又开热点?
- Android程序安装后图标不显示
- Git 常用命令速查