题目链接 \(Click Here\)_

\(200\)行纯干货的代码,一发\(WA\)掉真的是让人窒息,幸好最后找到了锅在哪。(差点就要弃掉了\(QAQ\))

【调出来的时候真的是要高兴到哭出来了\(TwT\)】

这个题有很多种写法,但是大多数都是强行水过去的,正解的话应该是\(SA\)或者\(SAM\)搞一些数据结构维护。我在这里选择的是线段树维护\(RMQ\),第一问就变成了区间颜色个数,第二问把第一问的答案差分对应到每个颜色上。放\(SA+\)莫队的人好像很少,这里我给一发清新脱俗又臭又长的代码供大家参考。

说句实话,如果我会\(SAM\)的话绝对不会用这种毒瘤写法。太\(TM\)难调了。

#include <bits/stdc++.h>
using namespace std; const int N = 600010;
const int INF = 0x7fffffff; #define ls (p << 1)
#define rs (p << 1 | 1) int n, m, l, len, s[N], id[N], height[N];
int sa[N], tp[N], rk[N], _rk[N], bin[N], qry[N], lenq[N]; void base_sort (int n, int m) {
for (int i = 1; i <= m; ++i) bin[i] = 0;
for (int i = 1; i <= n; ++i) bin[rk[tp[i]]]++;
for (int i = 1; i <= m; ++i) bin[i] += bin[i - 1];
for (int i = n; i >= 1; --i) sa[bin[rk[tp[i]]]--] = tp[i];
} void suffix_sort (int n, int m) {
for (int i = 1; i <= n; ++i) {
rk[i] = s[i], tp[i] = i;
}
base_sort (n, m);
for (int w = 1; w <= n; w <<= 1) {
int cnt = 0;
for (int i = n - w + 1; i <= n; ++i) {
tp[++cnt] = i;
}
for (int i = 1; i <= n; ++i) {
if (sa[i] > w) {
tp[++cnt] = sa[i] - w;
}
}
base_sort (n, m);
memcpy (_rk, rk, sizeof (rk));
rk[sa[1]] = cnt = 1;
for (int i = 2; i <= n; ++i) {
rk[sa[i]] = _rk[sa[i]] == _rk[sa[i - 1]] && _rk[sa[i] + w] == _rk[sa[i - 1] + w] ? cnt : ++cnt;
}
if (cnt == n) return;
m = cnt;
}
} void get_height (int n) {
int k = 0;
for (int i = 1; i <= n; ++i) {
if (k) --k;
int j = sa[rk[i] - 1];
while (s[i + k] == s[j + k]) ++k;
height[rk[i]] = k;
}
} struct Segment_Tree {
//维护height数组最小值的线段树
int a[N << 2]; void push_up (int p) {
a[p] = min (a[ls], a[rs]);
} void build (int l, int r, int p) {
if (l == r) {
a[p] = height[l];
return;
}
int mid = (l + r) >> 1;
build (l, mid, ls);
build (mid + 1, r, rs);
push_up (p);
} int query (int l, int r, int nl, int nr, int p) {
if (nl <= l && r <= nr) {
return a[p];
}
int mid = (l + r) >> 1, res = INF;
if (nl <= mid) res = min (res, query (l, mid, nl, nr, ls));
if (mid + 1 <= nr) res = min (res, query (mid + 1, r, nl, nr, rs));
return res;
}
}tr; struct Query {
int l, r, id, blo;
}q[N]; bool cmp (Query lhs, Query rhs) {
return lhs.blo == rhs.blo ? lhs.r < rhs.r : lhs.blo < rhs.blo;
} bool can_use (int l, int r, int lcp) {
return tr.query (1, len, l, r, 1) >= lcp;
} int have[N], ans1[N], ans2[N]; int main () {
cin >> n >> m;
int ban = 10001;
s[len = 0] = -1;
for (int i = 1; i <= n; ++i) {
for (int k = 0; k <= 1; ++k) {
cin >> l;
for (int j = 1; j <= l; ++j) {
cin >> s[++len];
id[len] = i;
}
s[++len] = ++ban;
}
}
for (int i = 1; i <= m; ++i) {
cin >> l;
lenq[i] = l;
qry[i] = len + 1;
for (int j = 1; j <= l; ++j) {
cin >> s[++len];
}
s[++len] = ++ban;
}
suffix_sort (len, ban);
get_height (len);
tr.build (1, len, 1);
int maxn = sqrt (len);
for (int i = 1; i <= m; ++i) {
q[i].id = i;
int l = 1, r = rk[qry[i]];
while (l < r) {
int mid = (l + r) >> 1;
if (can_use (mid, r, lenq[i])) {
r = mid;
} else {
l = mid + 1;
}
}
if (height[r] < lenq[i]) r++;
q[i].l = r - 1;
//确认左边界
l = rk[qry[i]], r = len;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (can_use (l, mid, lenq[i])) {
l = mid;
} else {
r = mid - 1;
}
}
if (height[l] < lenq[i]) l--;
q[i].r = l;
//确认右边界
q[i].blo = (q[i].l - 1) / maxn + 1;
//分块
}
sort (q + 1, q + 1 + m, cmp);
int l = 1, r = 0, tot = 0;
for (int i = 1; i <= m; ++i) {
while (l < q[i].l) {
--have[id[sa[l]]];
if (id[sa[l]] != 0 && have[id[sa[l]]] == 0) {
--tot;
ans2[id[sa[l]]] -= (m - i + 1);
}
++l;
}
while (l > q[i].l) {
--l;
if (id[sa[l]] != 0 && have[id[sa[l]]] == 0) {
++tot;
ans2[id[sa[l]]] += (m - i + 1);
}
++have[id[sa[l]]];
}
while (r > q[i].r) {
--have[id[sa[r]]];
if (id[sa[r]] != 0 && have[id[sa[r]]] == 0) {
--tot;
ans2[id[sa[r]]] -= (m - i + 1);
}
--r;
}
while (r < q[i].r) {
++r;
if (id[sa[r]] != 0 && have[id[sa[r]]] == 0) {
++tot;
ans2[id[sa[r]]] += (m - i + 1);
}
++have[id[sa[r]]];
}
ans1[q[i].id] = tot;
}
for (int i = 1; i <= m; ++i) printf ("%d\n", ans1[i]);
for (int i = 1; i <= n; ++i) printf ("%d ", ans2[i]);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. C# WebSocket模拟发送接收

    WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...

  2. Express static 托管静态文件 理解

    今天偶尔看了一下服务端渲染,遇到了express.static, 在以前学习webpack配置服务端渲染时,也使用express.static 中间件,两者配置不太一样,由于当时也没有认真学,所以 一 ...

  3. moogodb 安装及简单介绍

    1,安装Moogodb 因为是windows 64位操作系统,直接到官网上下载.msi文件,下载完成后点击安装,点击同意协议之后,出现下面的对话框, Choose Setup Type, 就是选择安装 ...

  4. 【XSY2774】学习 带花树

    题目描述 给你一个图,求最大匹配. 边的描述方式很特殊,就是一次告诉你\(c_i\)个点:\(d_1,d_2,\ldots,d_{c_i}\),表示这些点两两之间都有连边,也就是说,这是一个团.总共有 ...

  5. 【JDK源码】将JDK源码导入IDEA中

    新建工程 在IDEA中新建普通JAVA工程,步骤如下: 导入源码 首先可以通过如下方法找到工程目录. 在JDK安装目录下找到源码包src.zip,如下图 将src.zip包解压,并将src目录下的内容 ...

  6. 【BZOJ5417】[NOI2018]你的名字(线段树,后缀自动机)

    [BZOJ5417][NOI2018]你的名字(线段树,后缀自动机) 题面 BZOJ 洛谷 题解 首先考虑\(l=1,r=|S|\)的做法,对于每次询问的\(T\)串,暴力在\(S\)串的\(SAM\ ...

  7. HDU5909Tree Cutting

    题目大意 给定一颗树,每个点有点权,问对于每个m,有多少个联通块的权值异或和为m. 题解 解法1:可以考虑树形dp,设dp[u][i]表示以u为根的子树中u必须选,联通块权值异或值为i的联通块个数. ...

  8. layer 弹出层

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. 全文检索 -- Solr从概念到实战(一)

    全文检索: 将整个文本进行“分词”处理,在索引库中为分词得到的每一个词都建立索引,和用户搜索的关键词进行匹配.实现快速查找效果. 传统sql语句实现的局限性: select song_id,song_ ...

  10. MySQL使用普通用户访问返回ERROR 1698 (28000): Access denied for user 'root'@'localhost'

    这个问题最开始查资料都说要改密码,密码不对.其实不是这个样子都. 解决方法 修改/etc/mysql/my.cnf,添加以下内容 [mysqld] skip-grant-tables 重启mysql服 ...