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 一 ...
随机推荐
- 从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1
原文:从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1 事件聚合器EventAggregator [7.1updated]除了app部分,没 ...
- .net web api应用遇到的一些问题
1.调用webapi接口时,碰到一种情况: 通过webapi调用接口时,返回的json数据,死活转换不成对象,转换的对象一直为null: webapi端代码: [HttpGet] public str ...
- JavaScript基本概念(1)-声明提升
声明提升: function > var > other var提升的时候,只是声明提升,但是赋值还是会在原来的位置. Javascript Hoisting:In javascript, ...
- Struts2(十.在修改页显示照片列表并增加删除照片功能)
一.显示照片列表功能 struts2中一般的处理方式:先在action中,准备数据,转到jsp中显示 1.UserAction /** * 点击修改用户按钮跳转到修改用户界面 * 为用户准备照片,以便 ...
- python 终极篇 --- django 视图系统
Django的View(视图) 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误, ...
- python简单循环生成器
import time #循环生成器 def traversal_list(alist, i): while True: length = len(alist) i = i%(length) yiel ...
- JavaScript 正则
元字符 预定义类 边界 ^在中括号中时,匹配非hello的 str = 'hello world' str.match(/[^hello]/g) //[" ", "w&q ...
- 【转载】Android 内存溢出如何发生的。
[转载]Android 内存溢出如何发生的. 且谈Android内存溢出 前言 关于android的内存溢出在创新文档库中也有不少,网络上也有很多这方面的资料.所以这遍文章不算是正真意义上的创新,仅仅 ...
- vue.js学习之 跨域请求代理与axios传参
vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{}, ...
- Python3.5在Windows7环境下Scrapy库的安装
Python3.5在Windows7环境下Scrapy库的安装 忙活了一下午,总算是把Scrapy库给装完了,记下来给需要帮助的人 首先安装的环境:Windows7 64位 Python的版本是:3. ...