bzoj 3172 TJOI2013单词
2018-03-28 21:27
218 查看
http://www.elijahqi.win/archives/613
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
Sample Input
3
a
aa
aaa
Sample Output
6
3
1
HINT
Source
复习一下昨天的二分查找,但是复杂度感觉是玄学,还不如暴力跑得快
就是找到最长的满足区间内height都大于等于Len 求这个最大长度,分别在左右二分就可以了
nlogn 2628 ms
暴力
1384 ms
Description
某人读论文,一篇论文是由许多单词组成。但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次。
Input
第一个一个整数N,表示有多少个单词,接下来N行每行一个单词。每个单词由小写字母组成,N<=200,单词长度不超过10^6
Output
输出N个整数,第i行的数字表示第i个单词在文章中出现了多少次。
Sample Input
3
a
aa
aaa
Sample Output
6
3
1
HINT
Source
复习一下昨天的二分查找,但是复杂度感觉是玄学,还不如暴力跑得快
就是找到最长的满足区间内height都大于等于Len 求这个最大长度,分别在左右二分就可以了
nlogn 2628 ms
#include<cstdio> #include<cstring> #define N 1100000 #define N1 220 int n,n1,a ,m,k,rank[N<<1],rank1 ,sa ,count ,tmp ,height ,Log ,fmin [20]; char str1 ; struct node{ int st,len; }data[N1]; inline int min(int x,int y){return x<y?x:y;} inline int lcp(int x,int y){ x++;int t=Log[y-x+1]; return min(fmin[x][t],fmin[y-(1<<t)+1][t]); } void check(int st,int len){ int l1,r1; if (height[st]<len) l1=st;else{ int l=1,r=st-1; while (l<=r){ int mid=(l+r)>>1; if(lcp(mid,st)>=len) r=mid-1;else l=mid+1; } l1=l; } if (height[st+1]<len) r1=st;else{ int l=st+1,r=n; while (l<=r){ int mid=(l+r)>>1; if (lcp(st,mid)>=len) l=mid+1;else r=mid-1; } r1=r; } printf("%d\n",r1-l1+1); } int main(){ freopen("bzoj3172.in","r",stdin); scanf("%d",&n1);n=1;m=30; for (int i=1;i<=n1;++i) { scanf("%s",str1);int nn=strlen(str1);data[i].len=nn;data[i].st=n; for (int j=0;j<nn;++j) a[n+j]=str1[j]-'a'+1;n+=nn;a[n++]=m++; }n-=1; //for (int i=1;i<=n;++i) printf("%d ",a[i]); //for (int i=1;i<=n1;++i) printf("%d %d\n",data[i].st,data[i].len); for (int i=1;i<=n;++i) count[a[i]]=1; for (int i=1;i<=255;++i) count[i]+=count[i-1]; for (int i=1;i<=n;++i) rank[i]=count[a[i]]; k=0; for (int p=1;k!=n;p<<=1,m=k){ for (int i=1;i<=m;++i) count[i]=0; for (int i=1;i<=n;++i) count[rank[i+p]]++; for (int i=1;i<=m;++i) count[i]+=count[i-1]; for (int i=n;i>=1;--i) tmp[count[rank[i+p]]--]=i; for (int i=1;i<=m;++i) count[i]=0; for (int i=1;i<=n;++i) count[rank[i]]++; for (int i=1;i<=m;++i) count[i]+=count[i-1]; for (int i=n;i>=1;--i) sa[count[rank[tmp[i]]]--]=tmp[i]; memcpy(rank1,rank,sizeof(rank)>>1); rank[sa[1]]=k=1; for (int i=2;i<=n;++i){ if (rank1[sa[i]]!=rank1[sa[i-1]]||rank1[sa[i-1]+p]!=rank1[sa[i]+p]) ++k; rank[sa[i]]=k; } } // for (int i=1;i<=n;++i) printf("%d ",rank[i]); k=0; for (int i=1;i<=n;++i){ if (rank[i]==1) continue; k=k==0?0:k-1; while (a[i+k]==a[sa[rank[i]-1]+k]) ++k; height[rank[i]]=k; } //for (int i=1;i<=n;++i) printf("%d ",height[i]); Log[0]=-1; for (int i=1;i<=n;++i) Log[i]=Log[i>>1]+1; for (int i=1;i<=n;++i) fmin[i][0]=height[i]; for (int j=1;j<=Log ;++j){ for (int i=1;i<=n-(1<<j)+1;++i){ fmin[i][j]=min(fmin[i][j-1],fmin[i+(1<<(j-1))][j-1]); } } for (int i=1;i<=n1;++i) check(rank[data[i].st],data[i].len); return 0; }
暴力
1384 ms
#include<cstdio> #include<cstring> #define N 1100000 #define N1 220 int n,n1,a ,m,k,rank[N<<1],rank1 ,sa ,count ,tmp ,height ; char str1 ; struct node{ int st,len; }data[N1]; int main(){ freopen("bzoj3172.in","r",stdin); scanf("%d",&n1);n=1;m=30; for (int i=1;i<=n1;++i) { scanf("%s",str1);int nn=strlen(str1);data[i].len=nn;data[i].st=n; for (int j=0;j<nn;++j) a[n+j]=str1[j]-'a'+1;n+=nn;a[n++]=m++; }n-=1; //for (int i=1;i<=n;++i) printf("%d ",a[i]); //for (int i=1;i<=n1;++i) printf("%d %d\n",data[i].st,data[i].len); for (int i=1;i<=n;++i) count[a[i]]=1; for (int i=1;i<=255;++i) count[i]+=count[i-1]; for (int i=1;i<=n;++i) rank[i]=count[a[i]]; k=0; for (int p=1;k!=n;p<<=1,m=k){ for (int i=1;i<=m;++i) count[i]=0; for (int i=1;i<=n;++i) count[rank[i+p]]++; for (int i=1;i<=m;++i) count[i]+=count[i-1]; for (int i=n;i>=1;--i) tmp[count[rank[i+p]]--]=i; for (int i=1;i<=m;++i) count[i]=0; for (int i=1;i<=n;++i) count[rank[i]]++; for (int i=1;i<=m;++i) count[i]+=count[i-1]; for (int i=n;i>=1;--i) sa[count[rank[tmp[i]]]--]=tmp[i]; memcpy(rank1,rank,sizeof(rank)>>1); rank[sa[1]]=k=1; for (int i=2;i<=n;++i){ if (rank1[sa[i]]!=rank1[sa[i-1]]||rank1[sa[i-1]+p]!=rank1[sa[i]+p]) ++k; rank[sa[i]]=k; } } // for (int i=1;i<=n;++i) printf("%d ",rank[i]); k=0; for (int i=1;i<=n;++i){ if (rank[i]==1) continue; k=k==0?0:k-1; while (a[i+k]==a[sa[rank[i]-1]+k]) ++k; height[rank[i]]=k; } //for (int i=1;i<=n;++i) printf("%d ",height[i]); for(int i=1;i<=n1;++i){ int x=rank[data[i].st]; int l=x,r=x+1; while(height[l]>=data[i].len) --l; while(height[r]>=data[i].len) ++r;--r; printf("%d\n",r-l+1); } return 0; }
相关文章推荐
- 【BZOJ 3172】 [Tjoi2013]单词
- 【BZOJ 3172】[Tjoi2013]单词 Ac自动机
- 【BZOJ3172】【Tjoi2013】单词 AC自动机模板题
- [Tjoi2013][BZOJ3172] 单词
- bzoj3172 [Tjoi2013]单词
- BZOJ 3172: [Tjoi2013]单词 [AC自动机 Fail树]
- 【bzoj3172】 Tjoi2013—单词
- [省选前题目整理][BZOJ 3172][TJOI 2013]单词(AC自动机+fail树)
- BZOJ 3172 [Tjoi2013]单词 AC自动机 模板题
- bzoj 3172: [Tjoi2013]单词
- bzoj3172: [Tjoi2013]单词
- BZOJ 3172 [Tjoi2013]单词 AC自动机(fail树)
- [BZOJ]3172: [Tjoi2013]单词 AC自动机(或广义后缀自动机)
- [BZOJ3172] [TJOI2013] 单词 - AC自动机
- BZOJ 3172: [Tjoi2013]单词(fail树)
- BZOJ3172: [Tjoi2013]单词
- Bzoj 3172: [Tjoi2013]单词(fail树)
- 【BZOJ】【3172】【TJOI2013】单词
- BZOJ 3172: [Tjoi2013]单词 AC自动机/后缀自动机
- bzoj 3172: [Tjoi2013]单词 后缀数组+rmq+二分