离散化一下然后把姓名串和询问串都放一起做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. python打印列表的下标和值的例子:

    python打印列表的下标和值的例子: In [1]: list01=[1,4,5] In [10]: def funct01(ll):   ....:     for index,value in ...

  2. .net mvc数据库操作添加数据的几中方法

    1. Defining sets on a derived context 1) DbSet属性:指定集合为Entity类型 2) IDbSet属性 3) 只读set属性 public IDbSet& ...

  3. mysql 通过慢查询日志查写得慢的sql语句

    MySQL通过慢查询日志定位那些执行效率较低的SQL 语句,用--log-slow-queries[=file_name]选项启动时,mysqld 会写一个包含所有执行时间超过long_query_t ...

  4. Supervisor (进程管理利器) 使用说明 - 运维笔记

    一.Supervisor简单介绍supervisor是一个 Client/Server模式的系统,允许用户在类unix操作系统上监视和控制多个进程,或者可以说是多个程序.supervisor与laun ...

  5. ResultSet集合查询字段名称(转载)

    转自:https://blog.csdn.net/song_litao/article/details/84751351 public List<String> getColumnName ...

  6. 【2016.4.6】结对编程 终章 THE END

  7. PairWork-电梯调度程序结对编程【附加题】

    1 接口改进 1) 之前判断电梯是否闲置的函数不太好理解,重新修改了,如下所示: //是否停顿状态(停止的以及开门间隔>=0) public bool IsIdle { get { return ...

  8. git学习心得

    https://github.com/zhangxinn/test/tree/master 自己虽然在课堂上有认真的听老师讲解如何使用github,包括怎样在线学习,怎样在github上建立自己的仓库 ...

  9. CentOS 7 Install Adobe Flash Player

    From Officail Adobe Flash Site don't down (YUM )adobe-release-x86_64-1.0-1.noarch.rpm,but to downloa ...

  10. PP生产订单成本的计划、控制和结算

    SAP系统成本分析功能关注订单的成本,通过对计划成本和实际成本的比较分析,可以发现成本控制上的问题,以便及时解决问题.1.订单成本计划在基础数据齐全的基础上,系统可以自动滚算生产订单的成本.生产订单计 ...