bzoj2754 [SCOI2012]喵星球上的点名(后缀数组+暴力)
2017-08-24 18:00
501 查看
把所有串接在一起,打上分割符。SA求出h数组。然后就暴力。。每一个询问串往后往前扫h大于询问串长度的。然后暴力统计答案。。。复杂度很玄学。
tips:这题数据范围太大。。注意越界问题的细节。。
tips:这题数据范围太大。。注意越界问题的细节。。
#include <cstdio> #include <cstring> #include <algorithm> #define ll long long #define N 2020010 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int a ,nn,mm,n=0,m=10000,id,bel[150000],qn[50010],vis[20010],last; int rank[N<<1],rank1 ,sa ,h ,tmp ,count ,ans[20010]; int main(){ // freopen("a.in","r",stdin); nn=read();mm=read(); for(int i=1;i<=nn;++i){ int nnn=read(); while(nnn--){a[++n]=read();bel =i;} a[++n]=++m;nnn=read(); while(nnn--){a[++n]=read();bel =i;}a[++n]=++m; }last=n;id=n+1; for(int i=1;i<=mm;++i){ qn[i]=read(); for(int j=1;j<=qn[i];++j) a[++n]=read();a[++n]=++m; } for(int i=0;i<=m;++i) count[i]=0; for(int i=1;i<=n;++i) count[a[i]]=1; for(int i=1;i<=m;++i) count[i]+=count[i-1]; for(int i=n;i>=1;--i) rank[i]=count[a[i]]; int k=0;count[0]=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[tmp[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(rank1)); rank[sa[1]]=k=1; for(int i=2;i<=n;++i){ if(rank1[sa[i]]!=rank1[sa[i-1]]||rank1[sa[i]+p]!=rank1[sa[i-1]+p]) ++k; rank[sa[i]]=k; } }k=0; for(int i=1;i<=n;++i){ if(rank[i]==1){h[1]=0;continue;} if(i==1||h[rank[i-1]]<=1) k=0; if(k) --k; while(a[i+k]==a[sa[rank[i]-1]+k]) ++k; h[rank[i]]=k; } for(int i=1;i<=mm;++i){ int x=rank[id],res=0; int l=x,r=x+1; while(h[l]>=qn[i]) --l; while(h[r]>=qn[i]) ++r;--r; for(int j=l;j<=r;++j){ if(sa[j]>last) continue; if(vis[bel[sa[j]]]==i) continue; ans[bel[sa[j]]]++;res++; vis[bel[sa[j]]]=i; } printf("%d\n",res);id+=qn[i]+1; } for(int i=1;i<nn;++i) printf("%d ",ans[i]); printf("%d",ans[nn]); return 0; }
相关文章推荐
- 【BZOJ2754】【SCOI2012】喵星球上的点名 后缀数组优化暴力
- BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]
- BZOJ 2754([SCOI2012]喵星球上的点名-后缀数组统计序列集合中子序列出现次数)
- [BZOJ2754] [SCOI2012]喵星球上的点名解题报告|后缀数组
- BZOJ_2754__[SCOI2012]_喵星球上的点名_(暴力+后缀数组)
- bzoj2754:[SCOI2012]喵星球上的点名(后缀自动机)
- [luoguP2336] [SCOI2012]喵星球上的点名(后缀数组 + 暴力)
- 【bzoj2754】[SCOI2012]喵星球上的点名 AC自动机优化的暴力
- BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]
- [BZOJ2754] 喵星球上的点名 - AC自动机/后缀数组/后缀自动机/玄学♂暴力
- BZOJ2754[SCOI2012]喵星球上的点名
- BZOJ 2754: [SCOI2012]喵星球上的点名
- [BZOJ2754][SCOI2012]喵星球上的点名
- [BZOJ2754][SCOI2012]喵星球上的点名 后缀数组
- [BZOJ2754][SCOI2012]喵星球上的点名
- BZOJ2754 SCOI2012喵星球上的点名
- BZOJ 2754 【SCOI2012】 喵星球上的点名
- BZOJ 2754: [SCOI2012]喵星球上的点名
- BZOJ 2754 [SCOI2012]喵星球上的点名
- [BZOJ2754][SCOI2012]喵星球上的点名-AC自动机