(HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice…
2018-06-17 23:40:14来源:未知 阅读 ()
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=5558
S[a…b] means a substring of S ranging from S[a] to S[b] (0≤a≤b<N). If the first i letters have been encrypted, Alice will try to find a magic string P. Assuming P has K letters, P is the longest string which satisfies P=S[T...T+K−1] (0≤T<i,T+K≤N) and P=S[i…i+K−1](i+K≤N). In other words, P is a substring of S, of which starting address is within [0...i−1], and P is also a prefix of S[i...N−1]. If P exists, Alice will append integer Kand T to ciphertext. If T is not unique, Alice would select the minimal one. And then i is incremented by K. If P does not exist, Alice will append -1 and the ASCII code of letter S[i] to ciphertext, and then increment i by 1.
Obviously the first letter cannot be encrypted. That is to say, P does not exist when i=0. So the first integer of ciphertext must be -1, and the second integer is the ASCII code of S[0].
When i=N, all letters are encrypted, and Alice gets the final ciphertext, which consists of many pairs of integers. Please help Alice to implement this method.
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <bitset> using namespace std; const int N=1e5+5; char s[N]; int wa[N],wb[N],wv[N],wss[N]; int rankk[N],height[N],sa[N]; int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(char *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 ; } void calheight(char *r,int *sa,int n) { int i,j,k=0; for(i=1;i<=n;i++) rankk[sa[i]]=i; for(i=0;i<n;height[rankk[i++]]=k) for(k?k--:0,j=sa[rankk[i]-1];r[i+k]==r[j+k];k++); return ; } int main() { int T,Case=1; cin>>T; while(T--) { scanf("%s",s); int len=strlen(s); da(s,sa,len+1,130); calheight(s,sa,len); printf("Case #%d:\n",Case++); int i=0; while(i<len) { int pos,k=0; int rk=rankk[i]; int d=height[rk]; for(int j=rk;j>=1&&height[j]!=0;j--) { d=min(d,height[j]); if(d<k) break; if(sa[j-1]<i&&((d>k)||(d==k&&sa[j-1]<pos))) { k=d; pos=sa[j-1]; } } if(rk<len){ d=height[rk+1]; for(int j=rk+1; j<=len&&height[j]!=0; j++) { d=min(d,height[j]); if(d<k) break; if(sa[j]<i&&((d>k)||(d==k&&sa[j]<pos))) { k=d; pos=sa[j]; } } } if(k) printf("%d %d\n",k,pos),i+=k; else printf("%d %d\n",-1,(int)s[i++]); } } return 0; }
方法二:集合查找
#include <iostream> #include <algorithm> #include <stdio.h> #include <cstring> #include <cmath> #include <queue> #include <set> #include <bitset> using namespace std; const int N=1e5+5; char s[N]; int wa[N],wb[N],wv[N],wss[N]; int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } void da(char *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 ; } int rankk[N],height[N],sa[N],m[20][N]; void calheight(char *r,int *sa,int n) { int i,j,k=0; for(int i=1;i<=n;i++) rankk[sa[i]]=i; for(i=0;i<n;height[rankk[i++]]=k) for(k?k--:0,j=sa[rankk[i]-1];r[i+k]==r[j+k];k++); return ; } set<int>se; set<int>:: iterator it1,it2; int main() { int T,Case=1; cin>>T; while(T--) { scanf("%s",s); int len=strlen(s); da(s,sa,len+1,130); calheight(s,sa,len); memset(m,0,sizeof(m)); for(int i=2;i<=len;i++) m[1][i-1]=height[i]; for(int i=2;i<=(int)(log(len)/log(2));i++) { for(int j=1;j+(1<<i)-1<=len;j++) m[i][j]=min(height[j+(1<<(i-1))],min(m[i-1][j],m[i-1][j+(1<<(i-1))])); } printf("Case #%d:\n",Case++); int tot=0,minn=-999,maxn=9999999; se.clear(); se.insert(minn); se.insert(maxn); while(tot<len) { int k=0,p; int pos=tot; it1=se.upper_bound(rankk[tot]); it2=it1; while(*it1!=maxn) { int v=(int)(log(*it1-rankk[tot]+1)/log(2)); int f=min(m[v][rankk[tot]],m[v][*it1-(1<<v)+1]); if(f<k||f==0) break; if(f>k||(f==k&&sa[*it1]<p)){ k=f; p=sa[*it1]; } it1++; } it2--; while(*it2!=minn){ int v=(int)(log(rankk[tot]-*it2+1)/log(2)); int f=min(m[v][*it2],m[v][rankk[tot]-(1<<v)+1]); if(f<k||f==0) break; if(f>k||(f==k&&sa[*it2]<p)){ k=f; p=sa[*it2]; } it2--; } if(k==0) { printf("%d %d\n",-1,(int)s[tot]); tot++; } else { printf("%d %d\n",k,p); tot+=k; } for(;pos<tot;pos++) se.insert(rankk[pos]); } } return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- HDU-2955-Robberies(0-1背包) 2020-03-30
- hdu1455 拼木棍(经典dfs) 2020-02-29
- anniversary party_hdu1520 2020-02-16
- hdu1062 text reverse 2020-01-27
- hdu4841 2020-01-26
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash