传送门

原本的想法是把所有的串不管是名字还是询问都连起来,记录一下询问串在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]喵星球上的点名(后缀数组 + 暴力)的更多相关文章

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

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

  2. BZOJ 2754 SCOI 2012 喵星球上的点名 后缀数组 树状数组

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

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

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

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

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

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

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

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

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

  7. BZOJ 2754: [SCOI2012]喵星球上的点名 [AC自动机+map+暴力]

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

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

    洛咕 P2336 [SCOI2012]喵星球上的点名 先求出SA和height,一个点名串对应的就是一段区间,还有很多个点,就转化成了 有很多个区间,很多个点集,对每个区间计算和多少个点集有交,对每个 ...

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

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

随机推荐

  1. CF Gym 100187E Two Labyrinths (迷宫问题)

    题意:问两个迷宫是否存在公共最短路. 题解:两个反向bfs建立层次图,一遍正向bfs寻找公共最短路 #include<cstdio> #include<cstring> #in ...

  2. Object Modeling

    https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaEncyclopedia/Objec ...

  3. git clone 和 download 不一样,能用git clone 就用git clone,download的代码,经常出现安装bug

    git clone 和 download 不一样,能用git clone 就用git clone,download的代码,经常出现安装bug

  4. 【转载】Alpha、Beta、RC、GA版本的区别

    转自:http://www.blogjava.net/RomulusW/archive/2008/05/04/197985.html Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只 ...

  5. 服务器上搭建flowvisor平台

    之前全是在virtualbox上的Ubuntu虚拟机上测试的ovs以及pox, 现在我们开始在服务器上开始了 两台服务器上的ovs均是1.4.6版本 遇到一个问题:之前装的ovs down了 然后什么 ...

  6. Nginx: ubuntu系统上如何判断是否安装了Nginx?

    问题描述:ubuntu系统上,如何查看是否安装了Nginx? 解决方法:输入命令行:ps -ef | grep nginx master process后面就是Nginx的安装目录. 延伸:1. 如何 ...

  7. sql*plus常用指令介紹

    sql*plus常用指令介紹 1.用set指令來設定SQL*Plus的環境參數值 格式: Set 環境參數名 環境參數值 ex:set feedback on set feedback 8.用show ...

  8. Python Web 架构

    1. Django(全能型)2. Tornado3. BottlePython+Bottle+Sina SAE快速构建网站http://www.cnblogs.com/Xjng/p/3511983.h ...

  9. Diff Two Arrays-freecodecamp算法题目

    Diff Two Arrays(比较两个数组) 1.要求 比较两个数组,然后返回一个新数组 该数组的元素为两个给定数组中所有独有的数组元素.换言之,返回两个数组的差异. 2.思路 定义一个新数组变量, ...

  10. NOIP模拟赛 czy的后宫3

    [题目描述] 上次czy在机房妥善安排了他的后宫之后,他发现可以将他的妹子分为c种,他经常会考虑这样一个问题:在[l,r]的妹子中间,能挑选出多少不同类型的妹子呢? 注意:由于czy非常丧尸,所以他要 ...