UVALive 7902

来源:互联网 发布:淘宝情趣用品买家秀 编辑:程序博客网 时间:2024/06/03 07:38

题解思路:

考虑将所有的串都连起来,并且每个串本来的最后一个位置,这样防止之后考虑排名的时候会越界,设第一个字符串的长度为len,那么我们为0-len内的位置按排名从大到小枚举出来,这样就只考虑长度了不用再考虑大小了。那么我们以枚举的这个排名位置前后去扫描得出最大相同长度,因为要找到位置是在len之外。


#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>#include<set>using namespace std;typedef long long ll;const int mx = 3e5+10,mod = 1e9+7;char str[mx],st[mx];  int c[mx],wa[mx],wb[mx],sa[mx],height[mx],ran[mx],pos[mx];  void sort_sa(int m,int n){      int *x=wa,*y=wb,p=0;      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 k=1;p<n;k<<=1,m=p){          p=0;          for(int i=n-k;i<n;i++) y[p++]=i;//按个位排序           for(int i=0;i<n;i++)  if(sa[i]>=k) y[p++]=sa[i]-k;          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);x[sa[0]] = 0,p = 1;          for(int i=1;i<n;i++)          if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]) x[sa[i]]=p-1;          else x[sa[i]]=p++;      }  }  void get_height(){      int k=0,len=strlen(str);      for(int i=1;i<=len;i++) ran[sa[i]]=i;      for(int i=0;i<len;i++){          if(k) k--;          int j=sa[ran[i]-1];          while(str[j+k]==str[i+k]) k++;          height[ran[i]]=k;      }  }  int len,lens,n,m,back[mx];struct node{int pos,big;bool operator < (node A)const{return big < A.big;}}s[mx];int main(){int t,cas = 1;scanf("%d",&t);while(t--){scanf("%d",&n);scanf("%s",str);lens = len = strlen(str);for(int i=1;i<n;i++){scanf("%s",st);int lon = strlen(st);for(int j=0;j<lon;j++) str[lens+j] = st[j],back[lens+j] = lens+lon;lens += lon;}str[lens] = 0;sort_sa(150,lens+1); get_height();  printf("Case #%d: ",cas++);for(int i=0;i<len;i++){s[i].pos = i;s[i].big = ran[i];}sort(s,s+len);int ra,maxx,minn,po,ta,flag = 1,minlen = 1e9;for(int i=0;i<len;i++){ra = s[i].big,minn = 1e9,ta = ra+1;maxx = 0;while(ta<=lens&&height[ta]){minn = min(minn,height[ta]);po = sa[ta];if(po>=len){if(po+minn>back[po]) maxx = max(maxx,back[po]-po);else{maxx = max(maxx,minn);    break;}}ta++;}minn = 1e9;while(ra&&height[ra]){minn = min(minn,height[ra]);po = sa[ra-1];if(po>=len){if(po+minn>back[po]) maxx = max(maxx,back[po]-po);else{maxx = max(maxx,minn);    break;}}ra--;}if(maxx<len-s[i].pos){if(maxx<minlen){for(int j=0;j<=maxx;j++) st[j] = str[s[i].pos+j];st[maxx+1] = 0;minlen = maxx;flag = 0;}}}if(flag) puts("Impossible");else puts(st);}    return 0;}


原创粉丝点击