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 一 ...
随机推荐
- [Jmeter并发报错解决方案]org.apache.http.NoHttpResponseException: 10.0.4.147:8000 failed to respond
背景:公司模型框架是Nginx+uwsgi+Django+nginx,一开始使用Jmeter进行高并发请求测试,发现成功率只有50%,换用postman,成功率100%,代码进行高并发一样不会报错. ...
- c++ 面向对象程序设计
1. OOP:概述 2. 定义基类和派生类 3. 虚函数 4. 抽象基类 5. 访问控制与继承 6. 继承中的类作用域 7. 构造函数与拷贝控制 8. 容器与继承
- dubbo之注册管理中心
一.在dubbo的框架中注册中心是必要的一个环节,这个也是分布式部署的一个必要环节.在dubbo的架构基本图中可以看出,基本上所有的服务都是通过注册中心进行注册,然后在通过注册中心,暴露出接口来. 二 ...
- Ruby on Rails Tutorial 第2版 学习笔记
Ruby on Rails Tutorial 第2版 在线阅读:http://railstutorial-china.org/ 英文版:http://ruby.railstutorial.org/ru ...
- #define NULL ((void *)0)引起的风波
1. 看下宏定义的结构体 typedef struct { ]; //CMEI/IMEI ]; //server ]; //CMEI/IMEI } Options; 2. 定义的NULL #defin ...
- PHP使用Redis消息队列
1.redis安装 参考:菜鸟教程http://www.runoob.com/redis/redis-install.html 2.安装php的redis扩展 1)phpinfo()查看php版本信息 ...
- Selenium(Python)生成Html测试报告
由于Python3已经不支持HTMLTestRunner了, 无论是PyCharm还是pip都无法安装成功, 所以只能去 http://tungwaiyip.info/software/HTMLTes ...
- 初涉 Deep Drive Dataset
Berkeley 大学最近推出的针对自动驾驶的街景数据集,号称比 Cityscapes 数据量更大,可泛化性更好. 语义实例分割(Semantic Instance Segmentation) 数据集 ...
- CPU设计学习-流水线
各种名词 标量流水线 超级流水线 超标量流水线与多发射技术 经典五级流水线 IF |Instruction Fetch,取指 ID |Instruction Decode,译码 EX |Execute ...
- Balanced Lineup:线段树:区间最值 / RMQ
不要被线段树这个名字和其长长的代码吓到. D - Balanced Lineup Description For the daily milking, Farmer John's N cows (1 ...