比赛 20160415 评测结果 WWWTTEEWTT
题目名称 字符串 最终得分 0
用户昵称 咸鱼二号 运行时间 4.349 s
代码语言 C++ 内存使用 3.15 MiB
提交时间 2016-04-15 11:53:58
显示代码纯文本
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<utility>
#include<cstdlib>
#include<iomanip>	//cout<<setiosflags(ios::fixed)<<setprecision(2);
#include<ctime> //double a=(double)clock();	cout<<a<<endl;
#include<vector>
#include<queue>
using namespace std;
const int maxn=100010;
inline int read(){
	int x=0,ff=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')ff=-1; ch=getchar();}
	while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
	return ff*x;
}
inline void pointer_swap(int *&xx,int *&yy)
{int *zz=xx;xx=yy,yy=zz;}
inline int mymax(int xx,int yy)
{if(xx>yy)return xx;return yy;}
inline int mymin(int xx,int yy)
{if(xx<yy)return xx;return yy;}
int sa[maxn],rk[maxn],sx[maxn],sy[maxn],h[maxn],w[maxn];
int n,mark[100010];
char str[maxn];
void get_sa(){
	int i,j,m=128,p=0,*x=sx,*y=sy;
	for(i=1;i<=n;i++)w[x[i]=str[i]]++;
	for(i=1;i<=m;i++)w[i]+=w[i-1];
	for(i=n;i>=1;i--)sa[w[x[i]]--]=i;
	for(j=1,p=0;p<n;j<<=1,m=p){
		memset(w,0,sizeof(w));p=0;
		for(i=n-j+1;i<=n;i++)y[++p]=i;
		for(i=1;i<=n;i++)if(sa[i]>j)y[++p]=sa[i]-j;
		for(i=1;i<=n;i++)w[x[y[i]]]++;
		for(i=1;i<=m;i++)w[i]+=w[i-1];
		for(i=n;i>=1;i--)sa[w[x[y[i]]]--]=y[i];
		for(i=2,p=2,y[sa[1]]=1;i<=n;i++)
			if(str[sa[i]]==str[sa[i-1]]&&str[sa[i]+j]==str[sa[i-1]+j])
				y[sa[i]]=p;
			else y[sa[i]]=++p;
		pointer_swap(x,y);
	}
	for(i=1;i<=n;i++)rk[sa[i]]=i;
}
void get_h(){
	for(int i=1,j,k;i<=n;i++){
		j=sa[rk[i]+1];
		for(k=mymax(0,h[rk[i-1]]-1);str[i+k]==str[j+k];k++);
		h[rk[i]]=k;
	}
}
int N,K,cnt=-1,len,ans[maxn];
char tab[256],s[maxn];
int bel[maxn],tot;
bool vis[1010];
int myfind(int L,int R){
	memset(vis,0,sizeof(vis));tot=0;
	for(int i=1,j;i<=n;i++){
		j=i;
		while(str[L+j-i]==str[j]&&j-i<R-L)j++;
		if(j-i>=R-L)
			if(!vis[bel[i]])
				vis[bel[i]]=1,tot++;
	}
	return tot;
}
int main(){
	freopen("stringa.in","r",stdin);
	freopen("stringa.out","w",stdout);
	for(int i=1;i<=26;i++)
		tab[++cnt]=i+'A'-1;
	for(int i=0;i<=9;i++)
		tab[++cnt]=i+'0';
	tab[++cnt]='~';tab[++cnt]='!';tab[++cnt]='@';tab[++cnt]='#';tab[++cnt]='$';tab[++cnt]='%';tab[++cnt]='^';tab[++cnt]='&';tab[++cnt]='(';tab[++cnt]=')';tab[++cnt]='-';tab[++cnt]='=';tab[++cnt]='+';tab[++cnt]='_';
	cnt++;
	N=read(),K=read();
	for(int i=1;i<=N;i++){
		mark[i]=n+1;
		gets(s+1),len=strlen(s+1);
		for(int j=1;j<=len;j++)
			str[++n]=s[j],bel[n]=i;
		str[++n]=tab[n%cnt];
	}
	mark[N+1]=n+1;
	n--;
	//get_sa(),get_h();
	/*for(int i=1;i<=n;i++)
		printf("%c",str[i]);
	puts("");
	for(int i=1;i<=n;i++)
		printf("%d ",sa[i]);
	puts("");
	for(int i=1;i<=n;i++)
		printf("%d ",rk[i]);
	puts("");
	for(int i=1;i<=n;i++){
		for(int j=sa[i];j<=n;j++)
			printf("%c",str[j]);
		printf("\n%d\n",h[i]);
	}*/
	//后缀数组表示装完逼就跑。
	for(int i=1;i<=N;i++)
		for(int j=mark[i];j<mark[i+1]-1;j++)
			for(int k=j;k<mark[i+1]-1;k++)
				if(myfind(j,k)>=K)
					ans[i]++;
	//brute force
	for(int i=1;i<=N;i++)
		printf("%d ",ans[i]);
	puts("");
	return 0;
}