题意:给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串.注意本质相同的子串多次出现算多次,如1 1 aaa这组数据答案为6,贡献1WA.代码里有些部分是为了处理子串本质不同,可能没删干净.

因为字符串的总长不超过10^5,那么后缀的个数也不超过10^5。一个长为x的后缀可以产生x个子串,其中在至少k个串中出现的子串一定是长度从1 开始递增的连续几个.那么对每个后缀可以二分找出最多能够产生多么长的在至少k个串中出现的子串.把所有串连起来求后缀数组,二分一个长度mid之后可以找出有哪些后缀和当前后缀的lcp>=mid,那么长度为mid的子串就可以在这些位置出现(即这些后缀所在的字符串包含了这个长度为mid的子串)。这些后缀一定是排名连续的一段区间,预处理每个后缀属于哪个字符串,判断这段区间中出现的不同的归属种数是否大于等于k,那么主席树(参考HH的项链)就可以做了。时间复杂度O(nlog^2n)=O(跑得出)。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int str[maxn];int tot=;
int tmp[][maxn],sum[maxn],key[maxn];int sa[maxn],rank[maxn],height[maxn];
int st[maxn][],qlog[maxn];
void getsa(int n,int m){
int i,j,k,p,*rk=tmp[],*res=tmp[];
for(i=;i<m;++i)sum[i]=;
for(i=;i<n;++i)sum[rk[i]=str[i]]++;
for(i=;i<m;++i)sum[i]+=sum[i-];
for(i=n-;i>=;--i){
sa[--sum[rk[i]]]=i;
}
for(j=,p=;p<n;j<<=,m=p){
for(i=;i<m;++i)sum[i]=;
for(p=,i=n-j;i<n;++i)res[p++]=i;
for(i=;i<n;++i)if(sa[i]>=j)res[p++]=sa[i]-j;
for(i=;i<n;++i)sum[key[i]=rk[res[i]]]++;
for(i=;i<m;++i)sum[i]+=sum[i-];
for(i=n-;i>=;--i)sa[--sum[key[i]]]=res[i];
for(res[sa[]]=,p=,i=;i<n;++i)
res[sa[i]]=(rk[sa[i]]==rk[sa[i-]]&&rk[sa[i]+j]==rk[sa[i-]+j])?p-:p++;
swap(res,rk);
}
for(i=;i<n;++i)rank[sa[i]]=i;
for(i=,k=;i<n-;height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-];str[j+k]==str[i+k];++k);
for(int i=;i<n;++i)st[i][]=height[i];
for(int j=;(<<j)<n;++j){
for(int i=;i<n;++i){
st[i][j]=st[i][j-];
if(i+(<<j-)<n&&st[i+(<<j-)][j-]<st[i][j])st[i][j]=st[i+(<<j-)][j-];
}
}
for(int j=;(<<j)<n;++j)qlog[<<j]=j;
for(int i=;i<n;++i)if(!qlog[i])qlog[i]=qlog[i-];
}
int lcp(int a,int b){
if(a==b)return 0x7f7f7f7f;
a=rank[a];b=rank[b];
if(a>b)swap(a,b);
a++;int j=qlog[b-a+];
return min(st[a][j],st[b-(<<j)+][j]);
}
char buf[maxn];
int len[maxn],sumlen[maxn];
int belong[maxn];
struct node{
int sum;node* ch[];
node(){}
node(int x){sum=x;ch[]=ch[]=;}
}t[maxn*];int szoftree=;
node* newnode(int x){
t[++szoftree]=node(x);return t+szoftree;
}
void Insert(node* rt0,node* &rt,int l,int r,int k){
rt=newnode(rt0->sum+);
if(l==r)return;
int mid=(l+r)>>;
if(k<=mid){Insert(rt0->ch[],rt->ch[],l,mid,k);rt->ch[]=rt0->ch[];}
else {Insert(rt0->ch[],rt->ch[],mid+,r,k);rt->ch[]=rt0->ch[];}
}
int query(node* rt0,node* rt1,int l,int r,int ql,int qr){
if(ql>qr)return ;
if(ql<=l&&r<=qr)return rt1->sum-rt0->sum;
int mid=(l+r)>>,ans=;
if(ql<=mid)ans+=query(rt0->ch[],rt1->ch[],l,mid,ql,qr);
if(qr>mid) ans+=query(rt0->ch[],rt1->ch[],mid+,r,ql,qr);
return ans;
}
int last[maxn];
node* root[maxn];
typedef long long ll;
ll ans[maxn];
int lastsuf[maxn];
int pos;
int binary2(int l,int r,int x){
while(l<=r){
int mid=(l+r)>>;
if(lcp(pos,sa[mid])>=x)r=mid-;
else l=mid+;
}
return r+;
}
int binary3(int l,int r,int x){
while(l<=r){
int mid=(l+r)>>;
if(lcp(pos,sa[mid])>=x)l=mid+;
else r=mid-;
}
return l-;
}
int n,k;
int binary1(int suf,int l,int r){
pos=sa[suf];
while(l<=r){
int mid=(l+r)>>;
int left=binary2(,suf,mid),right=binary3(suf,tot,mid);//printf("%d %d %d\n",suf,left,right);
if(query(root[left-],root[right],,tot,,left)>=k)l=mid+;
else r=mid-;
}
return l-;
}
bool vis[maxn];
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i){
scanf("%s",buf);len[i]=strlen(buf);
for(int j=;j<len[i];++j){
str[tot++]=buf[j];
}
str[tot++]=+i;sumlen[i]=tot;
}
str[tot++]=;
getsa(tot,+n+);
for(int i=;i<=n;++i){
for(int j=sumlen[i-];j<sumlen[i]-;++j)belong[rank[j]]=i;
}
root[]=t+;root[]->ch[]=root[]->ch[]=t+;root[]->sum=;
for(int i=;i<tot;++i){
root[i]=root[i-];
if(belong[i]){
Insert(root[i],root[i],,tot,last[belong[i]]+);
last[belong[i]]=i;
}
}//printf("tot==%d\n",tot);
for(int i=;i<tot;++i){
if(belong[i]){//printf("%d\n",sa[i]);
int lo=,hi=sumlen[belong[i]]-sa[i]-;//长度上下界
// if(vis[belong[i]]){//printf("!");
// lo=max(lo,lcp(lastsuf[belong[i]],sa[i])+1);
// }
// lastsuf[belong[i]]=sa[i];vis[belong[i]]=true;
hi=binary1(i,lo,hi);//printf("%d %d\n",lo,hi);
ans[belong[i]]+=(hi-lo+);
}
}
for(int i=;i<=n;++i)printf("%lld ",ans[i]);
return ;
}

bzoj3473字符串&bzoj3277串的更多相关文章

  1. bzoj3473: 字符串 && bzoj3277串

    3473: 字符串 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 121  Solved: 53[Submit][Status][Discuss] D ...

  2. BZOJ3473&&BZOJ3277串

    BZOJ3473&&BZOJ3277串 题面 自己找去 HINT 对于所有串建立一个广义后缀自动机,对于每一个节点开一个set表示这个节点接受的子串在哪些串里出现过,然后在parent ...

  3. 汇编语言从键盘输入一个字符串(串长不大于80)以十进制输出字符串中非字母字符的个数(不是a to z或 A to Z)

    (1)从键盘输入一个字符串(串长不大于80). (2)以十进制输出字符串中非字母字符的个数(不是a to z或 A to Z). (3)输出原字符串且令非字母字符闪烁显示. (4)找出字符串中ASCI ...

  4. BZOJ3277 串 和 BZOJ3473 字符串

    字符串 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? 分析 参照自为风月马前卒和Candy?的题解. 广义后缀自动机不就是把很多串的SAM建到了一个S ...

  5. BZOJ3277——串

    0.题意:给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). 1.分析:这个题我问了吴大爷做法 首先建立后缀自动机,然后利用离线搞出每一个 ...

  6. PHP 中替换若干字符串字串为数组中的值,不用循环,非常高效

    替换某个字符串中的一个或若干个字串为数组中某些值 php本身有自带的函数,可以不用循环非常高效的实现其效果: 实例代码:   $phrase  = "You should eat fruit ...

  7. BZOJ3473: 字符串

    3473: 字符串 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 109  Solved: 47[Submit][Status] Descriptio ...

  8. SAP ABAP 处理字符串串串串串串串串(详细)

    关于ABAP中处理字符串的方法,非常详细,学习过程中总结一下分享给大家,,, ABAP/4 提供多个处理类型 C 即字符串 的数据对象的关键字. 处理字符串 的方法有: 1.拆分字符串split 2. ...

  9. BZOJ3473: 字符串【后缀数组+思维】

    Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...

随机推荐

  1. 前端页面加载速度优化---Ngnix之GZIP压缩

    gzip on; #开启Gzip gzip_static on;#是否开启gzip静态资源 #nginx对于静态文件的处理模块,该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的 ...

  2. 20145209刘一阳 《网络对抗》Exp7 网络欺诈技术防范

    20145209刘一阳 <网络对抗>Exp7 网络欺诈技术防范 一.应用SET工具建立冒名网站 要让冒名网站在别的主机上也能看到,需要开启本机的Apache服务,并且要将Apache服务的 ...

  3. 北京Uber优步司机奖励政策(3月29日

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. 成都Uber优步司机奖励政策(3月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  5. Emmet 技巧

    1. Lorem 产生一段 dummy text 2. $ 变量的使用 3. 插入img的长度和宽度 使用快捷键ctrl+u插入图片的长度和宽度 注意光标要停留在图片文件名上. 其他在Sublime中 ...

  6. Selenium(Python)驱动Chrome浏览器

    Chrome浏览器与chromedriver.exe驱动可以是官网上最新的, 随意! Chrome.py: from selenium import webdriverfrom selenium.we ...

  7. Linux命令应用大词典-第7章 字符串、文件和命令查找

    7.1 grep:字符串.文件和命令的查找 7.2 egrep:在文件或标准输入中查找模式 7.3 fgrep:在每个文件或是标准输入中查找模式 7.4 find:列出文件系统内符合条件的文件 7.5 ...

  8. lintcode 平面列表

    问题描述: 给定一个列表,该列表中的每个要素要么是个列表,要么是整数.将其变成一个只包含整数的简单列表. 样例: 给定 [1,2,[1,2]],返回 [1,2,1,2]. 给定 [4,[3,[2,[1 ...

  9. anaconda安装scrapy报错解决办法

    今天在用anaconda安装scrapy的时候遇见个坑,现在将解决办法发出来,供大家参考使用: 问题描述: anaconda安装scrapy,使用 conda install scrapy 命令.安装 ...

  10. qwe

    这次作业我负责的部分是把爬取完的聊天记录经行数据挖掘以及经行各种普通过滤高级过滤等. 运行截图如下: 数据分为四部分:账户名.qq/邮箱.包含关键词的发言次数.包含关键词的发言字数. 遇到的困难及解决 ...