离散化一下然后把姓名串和询问串都放一起做SA

bzoj3277串类似地,满足某一询问的后缀(就是和这个询问对应的后缀的LCP>=这个询问长度的后缀)的排名也是一个区间,把这个区间二分出来即可

现在要做的两个问题就变成了:

给定一些区间、一些点,每个点有对应的颜色(就是sa[i]对应的那个姓名串对应的人),问

1.每个区间中不同颜色的数量:同HH的项链

2.每个颜色被不同区间覆盖的数量:

  想法其实和1是类似的,扫到区间左端点的时候给a[i]++,扫到右端点的时候给a[对应左端点]--,然后每个点贡献的区间数就是pre[i]-pre[i的颜色上次出现位置],因为相当于我们每次算的是左端点在上次出现位置与现在位置之间的、右端点在现在位置之后的区间,是不重不漏的

(千万不要写出s[++j]=data[j]=rd();这种代码然后因为某些特性在某些地方A某些地方wa然后跑到讨论区去丢人)

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define ll long long
using namespace std;
const int maxn=4e5+,maxm=5e4+,maxq=1e5+; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} struct Node{
int l,r,i;
}que[maxq];
int NN,N,M,Q;
int data[maxn],s[maxn],bel[maxn];
int sa[maxn],rank[maxn],hei[maxn],rank1[maxn],tmp[maxn],cnt[maxn];
int st[maxn][],pos[maxq][];
int tr[maxn],L[maxn],lst[maxn],ans[maxq]; inline int lowbit(int x){return x&(-x);}
inline void add(int x,int y){
for(;x<=N;x+=lowbit(x)) tr[x]+=y;
}
inline int query(int x){
int re=;for(;x>;x-=lowbit(x)) re+=tr[x];return re;
} inline void getsa(){
int i,j=,k;
for(i=;i<=N;i++) cnt[s[i]]=;
for(i=;i<=M;i++) cnt[i]+=cnt[i-];
for(i=N;i;i--) rank[i]=cnt[s[i]]; for(k=;j!=N;k<<=){
memset(cnt,,sizeof(cnt));
for(i=;i<=N;i++) cnt[rank[i+k>N?:i+k]]++;
for(i=;i<=M;i++) cnt[i]+=cnt[i-];
for(i=N;i;i--) tmp[cnt[rank[i+k>N?:i+k]]--]=i;
memset(cnt,,sizeof(cnt));
for(i=;i<=N;i++) cnt[rank[i]]++;
for(i=;i<=M;i++) cnt[i]+=cnt[i-];
for(i=N;i;i--) sa[cnt[rank[tmp[i]]]--]=tmp[i];
memcpy(rank1,rank,sizeof(rank1));
rank[sa[]]=j=;
for(i=;i<=N;i++){
if(rank1[sa[i]]!=rank1[sa[i-]]||rank1[sa[i]+k>N?:sa[i]+k]!=rank1[sa[i-]+k>N?:sa[i-]+k]) j++;
rank[sa[i]]=j;
}M=j;
}
for(i=;i<=N;i++) sa[rank[i]]=i;
} inline void geth(){
for(int i=,j=;i<=N;i++){
if(rank[i]==) continue;
if(j) j--;
int x=sa[rank[i]-];
while(x+j<=N&&i+j<=N&&s[x+j]==s[i+j]) j++;
hei[rank[i]]=j;
}
} inline void getst(){
for(int i=N;i;i--){
st[i][]=hei[i];
for(int j=;st[i+(<<(j-))][j-];j++){
st[i][j]=min(st[i][j-],st[i+(<<(j-))][j-]);
}
}
} inline int rmq(int l,int r){
int x=log2(r-l+);
return min(st[l][x],st[r-(<<x)+][x]);
} inline void getq(int id,int p,int x){
int l0,r0,l,r;
if(hei[p+]<x) r0=p;
else{
l=p+,r=N;
while(l<=r){
int m=l+r>>;
if(rmq(p+,m)>=x) r0=m,l=m+;
else r=m-;
}
}
if(hei[p]<x) l0=p;
else{
l=,r=p;
while(l<=r){
int m=l+r>>;
if(rmq(m,p)>=x) l0=m-,r=m-;
else l=m+;
}
}
que[id].l=l0,que[id].r=r0,que[id].i=id;
} inline bool cmp(Node a,Node b){
return a.r<b.r;
} inline void solve(){
int i,j,k;
for(i=;i<=Q;i++){
getq(i,rank[pos[i][]],pos[i][]-pos[i][]+);
L[i]=que[i].l;
}sort(que+,que+Q+,cmp);
sort(L+,L+Q+); for(i=,j=;i<=N&&j<=Q;i++){
int x=bel[sa[i]];
if(x){
if(lst[x]) add(lst[x],-);
add(i,);lst[x]=i;
}
for(;que[j].r==i&&j<=Q;j++){
ans[que[j].i]=query(que[j].r)-query(que[j].l-);
}
}
for(i=;i<=Q;i++) printf("%d\n",ans[i]);
memset(ans,,sizeof(ans));
memset(lst,,sizeof(lst));
memset(tr,,sizeof(tr));
for(i=,j=,k=;i<=N;i++){
for(;j<=Q&&L[j]==i;j++) add(i,);
ans[bel[sa[i]]]+=query(i)-query(lst[bel[sa[i]]]);
lst[bel[sa[i]]]=i;
for(;k<=Q&&que[k].r==i;k++) add(que[k].l,-);
}for(i=;i<=NN;i++) printf("%d ",ans[i]);
} int main(){
//freopen("2336.in","r",stdin);
int i,j,k;
NN=N=rd(),Q=rd();
for(i=,j=;i<=N*+Q;i++){
int a=rd();
if(i>N*) pos[i-N*][]=j+,pos[i-N*][]=j+a;
for(k=;k<a;k++){
s[j]=data[++j]=rd();
if(i<=N*) bel[j]=(i+)/;
}
s[j]=data[++j]=-;
}N=j;
sort(data+,data+N+);
M=unique(data+,data+N+)-data-;
for(i=;i<=N;i++) s[i]=lower_bound(data+,data+M+,s[i])-data-;
M+=;
getsa();geth();getst();
solve();
return ;
}

luogu2336 喵星球上的点名 (SA+二分答案+树状数组)的更多相关文章

  1. BZOJ2754 [SCOI2012]喵星球上的点名 SA+莫队+树状数组

    题面 戳这里 题解 首先先把所有给出的姓名和询问全部接在一起,建出\(height\)数组. 某个串要包含整个询问串,其实就相当于某个串与询问串的\(lcp\)为询问串的长度. 而两个后缀\(Suff ...

  2. BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)

    吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ...

  3. [CSP-S模拟测试]:序列(二分答案+树状数组)

    题目传送门(内部题98) 输入格式 第一行一个整数$n$,第二行$n$个整数$a_1\sim a_n$,第三行$n$个整数$b_1\sim b_n$. 输出格式 一行一个整数表示$\max(r-l+1 ...

  4. cf1073D Berland Fair (二分答案+树状数组)

    用一个树状数组维护前缀和,每次我二分地找一个位置,使得我能一路买过去 但这个买不了 那以后肯定也都买不了了,就把它改成0,再从头二分地找下一个位置,直到这一圈我可以跑下来 然后就看跑这一圈要花多少钱. ...

  5. AtCoder Regular Contest 101 (ARC101) D - Median of Medians 二分答案 树状数组

    原文链接https://www.cnblogs.com/zhouzhendong/p/ARC101D.html 题目传送门 - ARC101D 题意 给定一个序列 A . 定义一个序列 A 的中位数为 ...

  6. 【序列莫队+二分答案+树状数组】POJ2104-K-th Number

    [题目大意] 给出一个长度为n的序列和m组查询(i,j,k),输出[i,j]中的第k大数. [思路] 先离散化然后莫队分块.用树状数组来维护当前每个值的个数,然后对于每次询问二分答案即可. 又一次实力 ...

  7. 4418: [Shoi2013]扇形面积并|二分答案|树状数组

    为何感觉SHOI的题好水. ..又是一道SB题 从左到右枚举每个区间,遇到一个扇形的左区间就+1.遇到右区间就-1,然后再树状数组上2分答案,还是不会码log的.. SHOI2013似乎另一道题发牌也 ...

  8. Luogu2336 SCOI2012 喵星球上的点名 SA、莫队

    传送门 一道很套路的题目 先将所有串拼在一起,两个不同的串之间放一个没有出现在任何串中的字符做分隔,然后SA 那么对于所有点名串能够点到的名字串在SA中对应一段区间 把这些区间拿出来然后莫队统计每一个 ...

  9. 【BZOJ2754】[SCOI2012]喵星球上的点名

    [BZOJ2754][SCOI2012]喵星球上的点名 题面 bzoj 洛谷 题解 这题有各种神仙做法啊,什么暴力\(AC\)自动机.\(SAM\)等等五花八门 我这个蒟蒻在这里提供一种复杂度正确且常 ...

随机推荐

  1. 微信小程序案例:获取微信访问用户的openid

    在微信开发项目中,获取openid是项目常遇的问题,本文通过主要讲解实现在微信小程序中如何获取用户的openid,案例实现非常简单 具体实现方法是通过登录接口获取登录凭证,然后通过request请求微 ...

  2. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(七)一次线上Mysql数据库崩溃事故的记录

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 文章简介 工作这几年,技术栈在不断更新,项目管理心得也增加了不少,写 ...

  3. Socket异步通信及心跳包同时响应逻辑分析(最后附Demo)。

    有段时间没有更博了,刚好最近在做Socket通信的项目,原理大致内容:[二维码-(加logo)]-->提供主机地址和端口号信息(直接使用[ThoughtWorks.QRCode.dll]比较简单 ...

  4. LVS负载均衡下session共享的实现方式-持久化连接

    之前简单介绍LVS负载均衡的高可用方案实施,下面详细说明LVS的session解决方案: LVS算法中,SH算法可以实现将同一客户端的请求总是发送给第一次指定的RS,除非该RS出现故障不能再提供服务. ...

  5. 继承:call、apply、bind方法

    javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. call,apply,bind这 ...

  6. D. Bicolorings

    传送门 [http://codeforces.com/contest/1051/problem/D] 题意 相当于有个2列n行得棋盘,棋盘上的格子只能是黑或者白,问你联通块为k得方案数有多少,结果对 ...

  7. SpringBoot-简单实例

    在进行实例之前,首先须确保电脑环境变量已经配置好,包括jdk.maven.此文章不做描述,不清楚自行百度. 第一步:来到springboot官网(https://start.spring.io/)下载 ...

  8. 申港集中运营平台Linux测试环境架构搭建

    架构图 服务一览 ESB安装 ESB全称为Enterprise Service Bus,即企业服务总线.ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素.ESB的出现改变了传统的软件架 ...

  9. SpringMvc 文件上传注意事项

    前端 1.表单提交方法与格式 <form class="form-horizontal" action="/biz/patent/edit" method ...

  10. PDF文档打印太慢怎么办

    如下图,用Adobe Acrobat打开PDF文件,然后[高级]-打勾[作为图像打印]即可