zoukankan      html  css  js  c++  java
  • bzoj5137:[Usaco2017 Dec]Standing Out from the Herd

    传送门

    不算太难,后缀数组
    将所有的字符串都连起来,就是注意减(height)的时候会有一部分被多减,加回来就好了
    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    void read(int &x) {
    	char ch; bool ok;
    	for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
    	for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
    }
    #define rg register
    const int maxn=2e5+10;char c[maxn];
    int T,n,tot=30,m=1e5+1000,sa[maxn],rk[maxn],id[maxn],iid[maxn],p[maxn];
    int h[maxn],x[maxn],y[maxn],num,a[maxn],len[maxn],ans[maxn],las[maxn];
    int main()
    {
    	read(T);
    	for(rg int i=1;i<=T;i++)
    	{
    		scanf("%s",c+1);len[i]=strlen(c+1);
    		for(rg int j=1;j<=len[i];j++)p[++n]=c[j]-'a',id[n]=i,iid[n]=j;
    		p[++n]=++tot;
    	}
    	for(rg int i=1;i<=n;i++)a[x[i]=p[i]]++;
    	for(rg int i=1;i<=m;i++)a[i]+=a[i-1];
    	for(rg int i=n;i;i--)sa[a[x[i]]--]=i;
    	for(rg int k=1;k<=n;k<<=1,num=0)
    	{
    		for(rg int i=n-k+1;i<=n;i++)y[++num]=i;
    		for(rg int i=1;i<=n;i++)if(sa[i]>k)y[++num]=sa[i]-k;
    		for(rg int i=1;i<=m;i++)a[i]=0;
    		for(rg int i=1;i<=n;i++)a[x[i]]++;
    		for(rg int i=1;i<=m;i++)a[i]+=a[i-1];
    		for(rg int i=n;i;i--)sa[a[x[y[i]]]--]=y[i];
    		for(rg int i=1;i<=n;i++)y[i]=x[i];
    		x[sa[1]]=num=1;
    		for(rg int i=2;i<=n;i++)
    			if(y[sa[i]]!=y[sa[i-1]]||y[sa[i-1]+k]!=y[sa[i]+k])x[sa[i]]=++num;
    			else x[sa[i]]=num;
    		if(num>=n)break;m=num;
    	}
    	for(rg int i=1;i<=n;i++)rk[sa[i]]=i;
    	for(rg int i=1,j,k=0;i<=n;h[rk[i++]]=k)
    		for(k=k?k-1:k,j=sa[rk[i]-1];p[j+k]==p[i+k];k++);
    	h[1]=0;
    	for(rg int i=1;i<=n;i++)
    	{
    		if(p[sa[i]]>30)break;num=min(h[i],num);
    		ans[id[sa[i]]]+=len[id[sa[i]]]-iid[sa[i]]+1-h[i];
    		if(id[sa[i]]!=id[sa[i-1]])ans[id[sa[i-1]]]-=h[i],ans[id[sa[i-1]]]+=num,num=h[i];
    	}
    	for(rg int i=1;i<=T;i++)printf("%d
    ",ans[i]);
    }
    
  • 相关阅读:
    ES6新特性:使用export和import实现模块化
    常见Linux/Unix开发辅助命令什锦
    Spark高速上手之交互式分析
    Lua中的元表与元方法
    explicit 构造函数
    【排序】基数排序(计数排序、桶排序)
    拓展训练—心得体会
    poj3411--Paid Roads(bfs+状压)
    点击单选button后的文字就可以选定相应单选button
    hdu 2349 最小生成树
  • 原文地址:https://www.cnblogs.com/lcxer/p/10607524.html
Copyright © 2011-2022 走看看