[luoguP2336] [SCOI2012]喵星球上的点名(后缀数组 + 暴力)
原本的想法是把所有的串不管是名字还是询问都连起来,记录一下询问串在sa数组中的位置
对于每个询问可以在sa数组中二分出左右边界,第一问用莫队,第二问差分乱搞。
结果发现我差分的思路想错了,先写了一个暴力,二分出左右边界之后直接从l枚举到r,想试试正确性,就交了一遍,结果过了。。。。
因为是暴力,可以不用二分左右边界,直接向左向右枚举扩展就可以了,st表也不用了,但我懒得改了
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 2000001 using namespace std; int n, m, cnt, mx, len;
int M[N], x[N], y[N], s[N], sa[N], b[N], d[N][21], Rank[N], Log[N], height[N], id[N], pos[N], ans[N], num[N]; inline int read()
{
int x = 0, f = 1;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
return x * f;
} inline void build_sa()
{
int i, k, p;
for(i = 0; i < mx; i++) b[i] = 0;
for(i = 0; i < len; i++) b[x[i] = s[i]]++;
for(i = 1; i < mx; i++) b[i] += b[i - 1];
for(i = len - 1; i >= 0; i--) sa[--b[x[i]]] = i;
for(k = 1; k <= len; k <<= 1)
{
p = 0;
for(i = len - k; i < len; i++) y[p++] = i;
for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = 0; i < mx; i++) b[i] = 0;
for(i = 0; i < len; i++) b[x[y[i]]]++;
for(i = 1; i < mx; i++) b[i] += b[i - 1];
for(i = len - 1; i >= 0; i--) sa[--b[x[y[i]]]] = y[i];
swap(x, y);
p = 1, x[sa[0]] = 0;
for(i = 1; i < len; i++)
x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;
if(p >= len) break;
mx = p;
}
} inline void build_height()
{
int i, j, k = 0;
for(i = 0; i < len; i++) Rank[sa[i]] = i;
for(i = 0; i < len; i++)
{
if(k) k--;
j = sa[Rank[i] - 1];
while(s[i + k] == s[j + k]) k++;
height[Rank[i]] = k;
}
} inline void build_st()
{
int i, j;
for(i = 1; i < len; i++)
{
Log[i] = log2(i);
d[i][0] = height[i];
}
Log[i] = log2(i);
for(j = 1; (1 << j) < len; j++)
for(i = 1; i + (1 << j) - 1 < len; i++)
d[i][j] = min(d[i][j - 1], d[i + (1 << j - 1)][j - 1]);
} inline int query(int l, int r)
{
int t = Log[r - l + 1];
return min(d[l][t], d[r - (1 << t) + 1][t]);
} inline int search2(int p, int llen)
{
int r = p, l = 1, mid;
while(l <= r)
{
mid = (l + r) >> 1;
if(query(mid, p) >= llen) r = mid - 1;
else l = mid + 1;
}
return r;
} inline int search1(int p, int llen)
{
p++;
int l = p, r = len - 1, mid;
while(l <= r)
{
mid = (l + r) >> 1;
if(query(p, mid) >= llen) l = mid + 1;
else r = mid - 1;
}
return l - 1;
} inline void solve()
{
int i, j, l, r;
for(i = 1; i <= m; i++)
{
r = j = search1(Rank[id[i]], M[i]);
l = j = search2(Rank[id[i]], M[i]);
for(j = l; j <= r; j++)
if(!num[pos[sa[j]]]++ && pos[sa[j]]) cnt++, ans[pos[sa[j]]]++;
printf("%d\n", cnt);
cnt = 0;
for(j = l; j <= r; j++) num[pos[sa[j]]] = 0;
}
for(i = 1; i <= n; i++) printf("%d ", ans[i]);
} int main()
{
int i, j, t;
n = read();
m = read();
for(i = 1; i <= n; i++)
for(j = 1; j <= 2; j++)
{
t = read();
while(t--)
{
pos[len] = i;
s[len++] = read() + 100000;
}
s[len++] = mx++;
}
for(i = 1; i <= m; i++)
{
M[i] = read();
id[i] = len;
for(j = 1; j <= M[i]; j++) s[len++] = read() + 100000;
s[len++] = mx++;
}
mx = 120000;
build_sa();
build_height();
build_st();
solve();
return 0;
}
[luoguP2336] [SCOI2012]喵星球上的点名(后缀数组 + 暴力)的更多相关文章
- BZOJ 2754: [SCOI2012]喵星球上的点名 [后缀数组+暴力]
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1906 Solved: 839[Submit][St ...
- BZOJ 2754 SCOI 2012 喵星球上的点名 后缀数组 树状数组
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2068 Solved: 907[Submit][St ...
- P2336 [SCOI2012]喵星球上的点名(后缀自动机+莫队+dfs序)
P2336 [SCOI2012]喵星球上的点名 名字怎么存?显然是后缀自动机辣 询问点到多少个喵喵喵其实就是 查询后缀自动机上parent树的一个子树 于是我们考虑莫队 怎么树上莫队呢 我们用dfs序 ...
- BZOJ2754: [SCOI2012]喵星球上的点名
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 680 Solved: 314[Submit][Sta ...
- 【BZOJ2754】[SCOI2012]喵星球上的点名
[BZOJ2754][SCOI2012]喵星球上的点名 题面 bzoj 洛谷 题解 这题有各种神仙做法啊,什么暴力\(AC\)自动机.\(SAM\)等等五花八门 我这个蒟蒻在这里提供一种复杂度正确且常 ...
- BZOJ 2754: [SCOI2012]喵星球上的点名
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 649 Solved: 305[Submit][Sta ...
- BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]
2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1902 Solved: 837[Submit][St ...
- 洛咕 P2336 [SCOI2012]喵星球上的点名
洛咕 P2336 [SCOI2012]喵星球上的点名 先求出SA和height,一个点名串对应的就是一段区间,还有很多个点,就转化成了 有很多个区间,很多个点集,对每个区间计算和多少个点集有交,对每个 ...
- 洛谷 P2336 [SCOI2012]喵星球上的点名 解题报告
P2336 [SCOI2012]喵星球上的点名 题目描述 a180285 幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有 \(N\) 个喵星人,每个喵星人的 ...
随机推荐
- 使用JS的画布制作一个瞄准镜
<canvas width="600" height="500" id="myCanvas"></canvas> & ...
- Servlet中的属性(attribute)和参数(parameter)的区别
1.引子 初学者对属性(attribute)和参数(parameter)容易搞混.没搞清他们的区别,项目中就可能出现一此莫名其妙的问题. 2.两者的区别 1) 属性(attribute) 属性是在后台 ...
- HTML5中的SSE(服务器推送技术)
本文原链接:https://cloud.tencent.com/developer/article/1194063 SSE技术详解:一种全新的HTML5服务器推送事件技术 前言 概述 基本介绍 与We ...
- nginx的工作流程
nginx请求处理流程 nginx进程结构 master进程:是作为worker进程管理的 worker进程:处理真正的请求的而master进程则是管控这些进程的工作方式的:缓存是在多个worker进 ...
- MySQL 外键 表的查询
自增补充 这是查看怎么创建的表, \G示旋转90度显示表的内容 表的自增的关键是** AUTO_INCREMENT=3**,在表中添加数据后,这个会自动改变,通过alert可以改变这个默认值 mysq ...
- webgis技术在智慧城市综合治理网格化社会管理平台(综治平台)的应用
网格化社会管理平台功能:1 实有人口管理人口数据管理按照人口分类进行管理,分为常住人口.流动人口.特殊人群.弱势群体,功能包括人口信息管理.归口负责.人房关联.统计汇总.地图监管服务等功能.人口信 ...
- vue-awesome-swiper插件爬坑
最近自己在做一个基于vue的知乎的移动端单页面,遇到很多坑,先说一下遇到最大的坑,其实并不推荐使用 vue-awesome-swiper,如果项目应用轮播,切换少的话.言归正传,现在来介绍vue-aw ...
- 【转】BP神经网络
学习是神经网络一种最重要也最令人注目的特点.在神经网络的发展进程中,学习算法的研究有着十分重要的地位.目前,人们所提出的神经网络模型都是和学习算 法相应的.所以,有时人们并不去祈求对模型和算法进行严格 ...
- 洛谷 P1835 素数密度
https://www.luogu.org/problemnew/show/P1835 对于40%,对每个数进行最大$O(\sqrt n)$的判断,因为n比较大所以超时. 想到线性筛,然而我们并不能筛 ...
- 了解swagger
https://blog.csdn.net/i6448038/article/details/77622977 随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了:前端渲染.先后端分离 ...