洛咕 P2336 [SCOI2012]喵星球上的点名


先求出SA和height,一个点名串对应的就是一段区间,还有很多个点,就转化成了

有很多个区间,很多个点集,对每个区间计算和多少个点集有交,对每个点集计算和多少个区间有交。

第一个,HH的项链的树状数组做法

第二个,因为是点集所以要去重,假设点集有\(a_1,a_2,\cdots,a_k\),可以对每个区间只再覆盖的第一个点做记录

就是记录\(\sum_{i=1}^k\sum_{\texttt{interval }[l,r]}\left[l\in[a_{i-1}+1,a_i],r\geq a_i\right]\)

#include<bits/stdc++.h>
#define il inline
#define vd void
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
std::vector<int>A[100010],B[100010],C[100010],S,P;
int len,x[400010],y[400010],t[400010],SA[400010],rk[400010];
int ht[400010];
il bool cmp(int a,int b,int k){return y[a]==y[b]&&y[a+k]==y[b+k];}
int ans1[100010],ans2[100010];
int lg[400010],st[19][400010];
il int query(int l,int r){
int g=lg[r-l+1];
return std::min(st[g][l],st[g][r-(1<<g)+1]);
}
std::vector<int>ins[400010],del[400010],p_del[400010];
int Tree[400010],Tree2[400010],lst[400010],LL[400010],RR[400010];
il vd update(int*t,int p,int x){while(p<=len)t[p]+=x,p+=p&-p;}
il int query(int*t,int r){int ret=0;while(r)ret+=t[r],r-=r&-r;return ret;}
int main(){
int n=gi(),m=gi();
for(int i=1;i<=n;++i){
len=gi();
while(len--)A[i].push_back(gi()+200000);
len=gi();
while(len--)B[i].push_back(gi()+200000);
}
for(int i=1;i<=m;++i){
len=gi();
while(len--)C[i].push_back(gi()+200000);
}
S.push_back(233333);
P.push_back(0);
int sep=0;
for(int i=1;i<=n;++i){
S.insert(S.end(),A[i].begin(),A[i].end());
S.push_back(++sep);
for(int j=0;j<A[i].size();++j)P.push_back(i);
P.push_back(0);
}
for(int i=1;i<=n;++i){
S.insert(S.end(),B[i].begin(),B[i].end());
S.push_back(++sep);
for(int j=0;j<B[i].size();++j)P.push_back(i);
P.push_back(0);
}
for(int i=1;i<=m;++i){
S.insert(S.end(),C[i].begin(),C[i].end());
S.push_back(++sep);
P.push_back(-i);
for(int j=0;j<C[i].size();++j)P.push_back(0);
}
len=S.size()-1;
int tot=400000;
for(int i=1;i<=len;++i)++t[x[i]=S[i]];
for(int i=1;i<=tot;++i)t[i]+=t[i-1];
for(int i=len;i;--i)SA[t[x[i]]--]=i;
for(int k=1;k<=len;k<<=1){
int p=0;
for(int i=0;i<=tot;++i)y[i]=0;
for(int i=len-k+1;i<=len;++i)y[++p]=i;
for(int i=1;i<=len;++i)if(SA[i]>k)y[++p]=SA[i]-k;
for(int i=0;i<=tot;++i)t[i]=0;
for(int i=1;i<=len;++i)++t[x[y[i]]];
for(int i=1;i<=tot;++i)t[i]+=t[i-1];
for(int i=len;i;--i)SA[t[x[y[i]]]--]=y[i];
std::swap(x,y),x[SA[1]]=p=1;
for(int i=2;i<=len;++i)x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
if(p>=len)break;tot=p;
}
for(int i=1;i<=len;++i)rk[SA[i]]=i;
int k=0;
for(int i=1;i<=len;++i){
if(rk[i]==len)continue;
if(k)--k;
int j=SA[rk[i]+1];
while(S[i+k]==S[j+k])++k;
ht[rk[i]]=k;
}
for(int i=2;i<=len;++i)lg[i]=lg[i>>1]+1;
for(int i=1;i<len;++i)st[0][i]=ht[i];
for(int i=1;i<=lg[len];++i)
for(int j=1;j+(1<<i)-1<len;++j)
st[i][j]=std::min(st[i-1][j],st[i-1][j+(1<<i-1)]);
for(int i=1;i<=len;++i)
if(P[SA[i]]<0){
int l=1,r=i,mid,sz=C[-P[SA[i]]].size();
while(l<r){
mid=(l+r)>>1;
if(query(mid,i-1)<sz)l=mid+1;
else r=mid;
}
int L=l;
ins[l].push_back(L);
LL[-P[SA[i]]]=l;
l=i,r=len;
while(l<r){
mid=(l+r)>>1;
if(query(i,mid)>=sz)l=mid+1;
else r=mid;
}
del[l+1].push_back(L);
p_del[l+1].push_back(-P[SA[i]]);
RR[-P[SA[i]]]=l;
}
for(int i=1;i<=len;++i){
if(P[SA[i]]>0){
update(Tree2,i,1);
if(lst[P[SA[i]]])update(Tree2,lst[P[SA[i]]],-1);
}
for(int j=0;j<ins[i].size();++j)update(Tree,ins[i][j],1);
for(int j=0;j<del[i].size();++j)update(Tree,del[i][j],-1);
if(P[SA[i]]>0){
ans1[P[SA[i]]]+=query(Tree,i)-query(Tree,lst[P[SA[i]]]);
lst[P[SA[i]]]=i;
}
for(int j=0;j<del[i+1].size();++j)ans2[p_del[i+1][j]]=query(Tree2,RR[p_del[i+1][j]])-query(Tree2,LL[p_del[i+1][j]]-1);
}
for(int i=1;i<=m;++i)printf("%d\n",ans2[i]);
for(int i=1;i<=n;++i)printf("%d ",ans1[i]);
puts("");
return 0;
}

洛咕 P2336 [SCOI2012]喵星球上的点名的更多相关文章

  1. 洛谷 P2336 [SCOI2012]喵星球上的点名 解题报告

    P2336 [SCOI2012]喵星球上的点名 题目描述 a180285 幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有 \(N\) 个喵星人,每个喵星人的 ...

  2. 洛谷P2336 [SCOI2012]喵星球上的点名(后缀数组+莫队)

    我学AC自动机的时候就看到了这题,想用AC自动机结果被学长码风劝退-- 学后缀数组时又看到了这题--那就写写后缀数组做法吧 结果码风貌似比当年劝退我的学长还毒瘤啊 对所有的模式串+询问串,不同串之间用 ...

  3. P2336 [SCOI2012]喵星球上的点名(后缀自动机+莫队+dfs序)

    P2336 [SCOI2012]喵星球上的点名 名字怎么存?显然是后缀自动机辣 询问点到多少个喵喵喵其实就是 查询后缀自动机上parent树的一个子树 于是我们考虑莫队 怎么树上莫队呢 我们用dfs序 ...

  4. Luogu P2336 [SCOI2012]喵星球上的点名

    题目链接 \(Click Here\)_ \(200\)行纯干货的代码,一发\(WA\)掉真的是让人窒息,幸好最后找到了锅在哪.(差点就要弃掉了\(QAQ\)) [调出来的时候真的是要高兴到哭出来了\ ...

  5. P2336 [SCOI2012]喵星球上的点名(SA+莫队)

    题面传送门 一道还算有点含金量的 SA 罢-- 首先按照套路我们把读入的所有字符串都粘在一起,中间用分隔符隔开并建出后缀数组出来. 我们考虑对于一个固定的字符串 \(s\),什么样的字符串 \(t\) ...

  6. BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1906  Solved: 839[Submit][St ...

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

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

  8. BZOJ 2754: [SCOI2012]喵星球上的点名

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 649  Solved: 305[Submit][Sta ...

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

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 680  Solved: 314[Submit][Sta ...

随机推荐

  1. Session["Write"] = "Write";

    Session["Write"] = "Write"; 将Session使用起来,建立起回话,这样才能保证会话中保持SessionID不变,否者,如果你直接使用 ...

  2. Oracle EBS OM 已存在的OM订单增加物料

    DECLARE l_header_rec OE_ORDER_PUB.Header_Rec_Type; l_line_tbl OE_ORDER_PUB.Line_Tbl_Type; l_action_r ...

  3. 十个强大的DevOps基础设施自动化工具,不容错过

    Devops基础设施自动化的工具 有许多工具用于基础设施自动化.使用哪个工具决定于体系结构和基础设施的需求.下面我们列出了一些伟大的工具,用于不同类别配置管理.编制.持续集成.监控等. 1.Chef ...

  4. sql点滴44—mysql忘记root密码

    1. 首先检查mysql服务是否启动,若已启动则先将其停止服务,可在开始菜单的运行,使用命令: net stop mysql 打开第一个cmd1窗口,切换到mysql的bin目录,运行命令: mysq ...

  5. MySql详解(五)

    MySql详解(五) MySql库的管理 一.创建库 create database [if not exists] 库名[ character set 字符集名]; 二.修改库 alter data ...

  6. 为什么重写equals必须重写hashcode?

    示例代码: class User { private String name; public User(String name) { this.name = name; } @Override pub ...

  7. Hello Shader之Hello Trangle

    这两天配了一下现代OpenGL的开发环境,同时看了一下基础知识和编程规范 写了一个编译GLSL语言的前端程序和一个Hello trangle的程序 另外,推荐两个资源 1.学习网站Learn Open ...

  8. AES块加密与解密

    AES块加密与解密 解密目标 在CBC和CTR两种模式下分别给出十篇加密的样例密文,求解密一篇特定的密文 解密前提 全部密文及其加密使用的key都已给出 加密的方法遵循AES的标准 解密过程分析 实验 ...

  9. SQL必知必会摘要

    数据检索 2.2 检索单个列 SELECT prod_name FROM Products; SQL语句不区分大小写   2.3 检索多个列 SELECT prod_name,prod_id,prod ...

  10. oracle 数据库 NLS_CHARACTERSET 字符集的修改

    修改Oracle 数据库字符集总结:修改方式大约有3种:方法一: (最安全的方法)数据库创建以后,如果需要修改字符集,通常需要重建数据库,通过导入导出的方式来转换.方法二: (最常用的方法)通过 &q ...