bzoj3473字符串&bzoj3277串
题意:给定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串的更多相关文章
- bzoj3473: 字符串 && bzoj3277串
3473: 字符串 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 121 Solved: 53[Submit][Status][Discuss] D ...
- BZOJ3473&&BZOJ3277串
BZOJ3473&&BZOJ3277串 题面 自己找去 HINT 对于所有串建立一个广义后缀自动机,对于每一个节点开一个set表示这个节点接受的子串在哪些串里出现过,然后在parent ...
- 汇编语言从键盘输入一个字符串(串长不大于80)以十进制输出字符串中非字母字符的个数(不是a to z或 A to Z)
(1)从键盘输入一个字符串(串长不大于80). (2)以十进制输出字符串中非字母字符的个数(不是a to z或 A to Z). (3)输出原字符串且令非字母字符闪烁显示. (4)找出字符串中ASCI ...
- BZOJ3277 串 和 BZOJ3473 字符串
字符串 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? 分析 参照自为风月马前卒和Candy?的题解. 广义后缀自动机不就是把很多串的SAM建到了一个S ...
- BZOJ3277——串
0.题意:给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). 1.分析:这个题我问了吴大爷做法 首先建立后缀自动机,然后利用离线搞出每一个 ...
- PHP 中替换若干字符串字串为数组中的值,不用循环,非常高效
替换某个字符串中的一个或若干个字串为数组中某些值 php本身有自带的函数,可以不用循环非常高效的实现其效果: 实例代码: $phrase = "You should eat fruit ...
- BZOJ3473: 字符串
3473: 字符串 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 109 Solved: 47[Submit][Status] Descriptio ...
- SAP ABAP 处理字符串串串串串串串串(详细)
关于ABAP中处理字符串的方法,非常详细,学习过程中总结一下分享给大家,,, ABAP/4 提供多个处理类型 C 即字符串 的数据对象的关键字. 处理字符串 的方法有: 1.拆分字符串split 2. ...
- BZOJ3473: 字符串【后缀数组+思维】
Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...
随机推荐
- CSS基础part2
CSS属性操作-文本 文本颜色 <head> <style> p{ /*color:#8B5742 ;色码表*/ color: RGBA(255,0,0,0.5); /*调色, ...
- 如何往eclipse中导入maven项目
现在公司中大部分项目可能都是使用maven来构建,假如现在摆在你面前有一个maven的项目,如果你要学习它,如何将它导入到像eclipse这样的集成开发工具中呢,以项目public_class_1为例 ...
- 软件测试的基础-摘自《selenium实践-基于电子商务平台》
软件测试的方法 一.等价类划分法 等价类划分法是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少量具有代表性的数据作为测试用例. 有两种不同的情况:有效等价和无效等 ...
- Git与远程仓库关联以及关联错误解决方法
假设你github的用户名是 helloworld ,你在上面创建了一个 名为 hello 的 repository. 一. 与本地仓库进行关联 1.1用原生ssh进行关联,速度快: git re ...
- leetcode-位1的个数(位与运算)
位1的个数 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量). 示例 : 输入: 11 输出: 3 解释: 整数 11 的二进制表示为 00000 ...
- 【token接口】-jmeter
token 接口 3步骤 1.登录接口 2.提取登录接口的token 3.http 信息管理头 把提取的cookie传入 就可以了
- CSP201709-1:打酱油
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- HTMLTestRunner解决UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe5 in position 108: ordinal not in range(128)
其中HTML和数据库都是设置成utf-8格式编码,插入到数据库中是正确的,但是当读取出来的时候就会出错,原因就是python的str默认是ascii编码,和unicode编码冲突,就会报这个标题错误. ...
- 20170413B端业务访问故障排查思路
现象: 1.全国用户电视端页面无法显示,刷不出版面. 2.后端服务无法打开,报错,504,502 显示服务器端业务故障超时. 3.其他业务也出现缓慢情况,并不严重. 排查: 1.系统服务排查,常规 ...
- (转)apktool+dex2jar+jd_gui
转:http://www.cnblogs.com/MichaelGuan/archive/2011/10/25/2224578.html apktool: 可以解析资源文件,比如布局文件xml等,方便 ...