比赛 |
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;
}