http://www.lydsy.com/JudgeOnline/problem.php?id=3879

SvT的中文是后缀虚树?

反正本蒟蒻不懂,还是$O(nlogn)$的后缀数组和单调栈维护来做,fye学姐讲了这种学法(当时并没有听懂QwQ),xiaoyimi教会了我这种做法→xiaoyimi的题解

一开始贡献了2次TLE,以为是玄学的死循环,果断挂起对拍器拍了一晚上,然后在回家的路上才想起来TLE是因为提交的时候忘删freopen了

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 500003;
const ll p = 23333333333333333ll;
int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 3) + (k << 1) + c - '0';
return k * fh;
} int c[N], t1[N], t2[N]; void st(int *x, int *y, int *sa, int n, int m) {
for(int i = 0; i < m; ++i) c[i] = 0;
for(int i = 0; i < n; ++i) ++c[x[y[i]]];
for(int i = 1; i < m; ++i) c[i] += c[i - 1];
for(int i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i];
} void mkhz(int *r, int *sa, int n, int m) {
int *x = t1, *y = t2, *t, p, i, j;
for(i = 0; i < n; ++i) x[i] = r[i], y[i] = i;
st(x, y, sa, n, m);
for(p = 1, j = 1; p < n; m = p, j <<= 1) {
for(p = 0, i = n - j; i < n; ++i) y[p++] = i;
for(i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
st(x, y, sa, n, m);
for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; ++i)
x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + j] == y[sa[i - 1] + j] ? p - 1 : p++;
}
} void mkh(int *r, int *sa, int *rank, int *h, int n) {
int k = 0, j, i;
for(i = 0; i < n; ++i) rank[sa[i]] = i;
for(i = 1; i < n; h[rank[i++]] = k)
for(k ? --k : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; ++k);
} char s[N];
int n, m, sa[N], rank[N], r[N], h[N], f[N][20], Log_2[N], a[N]; int get_min(int l, int r) {
int len = Log_2[r - l];
return min(f[l][len], f[r - (1 << len)][len]);
} int get_LCP(int l, int r) {
l = rank[l]; r = rank[r];
if (l > r) swap(l, r);
return get_min(l, r);
} bool cmp(int x, int y) {
return rank[x] < rank[y];
} int sta[N], top, bef[N], size[N]; void sub(ll &x, ll y) {
x -= y; if (x < 0) x += p;
} void add(ll &x, ll y) {
x += y; if (x > p) x -= p;
} int main() {
n = in(); m = in();
scanf("%s", s + 1);
r[0] = 0;
for(int i = 1; i <= n; ++i) r[i] = s[i] - 'a' + 1;
mkhz(r, sa, n + 1, 27);
mkh(r, sa, rank, h, n + 1); for(int i = 0; i < n; ++i) f[i][0] = h[i + 1];
for(int j = 1; j < 20; ++j)
for(int i = 0; i < n; ++i) {
if (i + (1 << (j - 1)) >= n) break;
f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
} int tmp = 0;
for(int i = 1; i <= n; ++i) {
if ((1 << (tmp + 1)) < i) ++tmp;
Log_2[i] = tmp;
} int tot; ll sum, ans = 0;
while (m--) {
tot = in();
for(int i = 1; i <= tot; ++i) a[i] = in();
sort(a + 1, a + tot + 1, cmp);
tot = unique(a + 1, a + tot + 1) - a;
--tot;
for(int i = 1; i < tot; ++i) bef[i] = get_LCP(a[i], a[i + 1]); top = 0; sum = 0; ans = 0;
for(int i = 1; i < tot; ++i) {
size[i] = 1;
while (top && bef[i] < bef[sta[top]]) {
sub(sum, 1ll * bef[sta[top]] * size[sta[top]] % p);
size[i] += size[sta[top]];
--top;
}
sta[++top] = i;
add(sum, 1ll * bef[i] * size[i] % p);
add(ans, sum);
}
printf("%lld\n", ans);
} return 0;
}

再一次被自己的智商感动QAQ

【BZOJ 3879】SvT的更多相关文章

  1. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  2. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  3. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  4. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  5. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  6. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  7. 【BZOJ 2132】圈地计划 && 【7.22Test】计划

    两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...

  8. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  9. 【BZOJ 1032】 [JSOI2007]祖码Zuma

    [题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1032 [题意] [题解] /* 设f[i][j]表示从第i个珠子开始的j个珠子被消除; ...

随机推荐

  1. Java开发之Servlet之间的跳转

    一.转向(Forward) 1.要点说明 转向是通过RequestDispatcher对象的forward()方法来实现的.RequestDispatcher可以通过HttpServletReques ...

  2. Objective-C声明在头文件和实现文件中的区别

    Objective-C声明在头文件和实现文件中的区别 转自codecloud(有整理) 调试程序的时候,突然想到这个问题,百度一下发现有不少这方面的问答,粗略总结一下: 属性写在.h文件中和在.m文件 ...

  3. 石子合并[DP-N3]

    题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将N堆石子合并成1 ...

  4. RecyclerView,CardView导入和使用(Demo)

    简介: 这篇文章是ANDROID L——Material Design详解(UI控件)的一个补充或者说是应用实例,如果有时间建议大家稍微浏览一下上篇文章. 本文主要介绍Android L新增加的两个U ...

  5. Ant 命令行编译Android项目

    首先把android sdk下的tools目录加到系统path环境变量里, 要么就得直接指定android.bat的绝对路径 对于一个新项目, 可以用这个命令创建需要的ant编译环境(可以看到andr ...

  6. 执行sudo时报错:effective uid is not 0

    http://jingyan.baidu.com/article/c45ad29cd83d4b051753e232.html     今天将 / 授权给了一个普通用户 导致一些问题. 启事: 操作前一 ...

  7. 程序开发使用docker部署

    我们公司自己研发了一套 grand-line 系统,使用 docker 来部署项目. 我是第一批小白鼠,一开始网络差,build 一次要半个小时,连接进入 web shell 也很慢,部署一个微信项目 ...

  8. dirtycow漏洞

    dirtycow漏洞,原理还没看懂,找了几个PoC实验了一下. dirtyc0w.c我在CentOS和Kali上都失败了 pokemon.c在CentOS上成功修改了只读文件,不过修改的不是很顺利,结 ...

  9. servlet乱码问题总结

    在学习时servlet乱码问题还是挺严重的,总结一下有三种情况 1.新建HTML页面后浏览出现乱码 2.以post形式请求时出现乱码 3.以get形式请求时出现乱码 让我们一个一个来解决吧 1.新建H ...

  10. hibernate Expression详解

    关键字: hibernate expression hibernate Expression详解Expression.gt:对应SQL条件中的"field > value " ...