他要求的就是lcp(x,y)>=i的(x,y)的个数和a[x]*a[y]的最大值 做一下后缀和,就只要求lcp=i的了 既然lcp(x,y)=min(h[rank[x]+1],..,[h[rank[y]]]) 那么我们求出来对于每一个h,以它作为最小值的区间的左右端点就可以了,这个可以用单调栈,具体做法见Neat Tree(?哪里具体了) 假设L是i左面第一个h小于等于它的,R是i右面第一个小于它的(一定要一边有=一边没有,很关键) 那就相当于lcp(x,y)=h[i] ,rank[x]∈[L,…
传送门 感觉题目讲的很不清楚-- 题目意思就是给出一个长度为\(n\)的字符串,求对于\(r=0,1,...,n-1\),求出\(LCP(suffix_p,suffix_q) \geq r\)的无序数对\((p,q)\)的数目,并令一对无序数对的价值为\(val_p \times val_q\),则还要求对于每一个\(r\),所有满足上述条件的无序数对中的最大价值 跟后缀\(LCP\)长度有关,直接上\(SA\).求出\(sa\)数组和\(height\)数组,我们考虑如何实现对于每一个\(r\…
原文链接http://www.cnblogs.com/zhouzhendong/p/9026184.html 题目传送门 - Codeforces 802I 题意 求一个串中,所有本质不同子串的出现次数的平方和. $|s|\leq 10^5$ 题解 首先,这一题用 SAM 做就是模板题,比较简单. 但是,本着练一练 SA 的心态,我开始了 SA+单调栈 的苦海. 真毒瘤. 这里讲一讲 SA 的做法,也是经典的做法. SA 闭着眼睛先写了再说. 首先,我们考虑出现次数大于 $1$ 次的子串. 考虑…
原文链接https://www.cnblogs.com/zhouzhendong/p/9256033.html 题目传送门 - CF873F 题意 给定长度为 $n$ 的字符串 $s$,以及给定这个字符串每一个位置是否 “禁止结尾” 的信息. 一个字符串 $a$ 的价值为 $|a|\times f(a)$ . 其中 $f(a)$为 $a$ 在 $s$ 中的匹配次数(如果匹配的结尾为禁止结尾点,那么不算匹配成功) 问在所有的字符串 $a$ 中,$\max(|a|\times f(a)$ 的值. $…
题意 给出一个字符串\(s\)和\(q\)个询问. 每次询问给出两个长度分别为\(k,l\)的序列\(a\)和序列\(b\). 求\(\sum_{i=1}^{k}\sum_{j=1}^{l}lcp(s[a_i-n],s[b_j-n])\) Solution \(SA\)练习题. 求出\(height\)数组后,每次询问相当于询问\(l*k\)个区间\(min\)之和. 岂不单调栈? 对没错,这个题解就是提供给你代码对拍的 #include<bits/stdc++.h> #define For(…
题面 戳这里 题解 考虑把要求的那个东西拆开算,前面一个东西像想怎么算怎么算,后面那个东西在建出\(height\)数组后相当于是求所有区间\(min\)的和*2,单调栈维护一波即可. #include<bits/stdc++.h> #define For(i,x,y) for (int i=(x);i<=(y);i++) #define Dow(i,x,y) for (int i=(x);i>=(y);i--) #define cross(i,k) for (int i=firs…
把两个串中间加一个未出现字符接起来,然后求SA 然后把贡献统计分为两部分,在排序后的后缀里,属于串2的后缀和排在他前面属于串1的后缀的贡献和属于串1的后缀和排在他前面属于串2的后缀的贡献 两部分分别作,都用单调栈维护一段里的height最小值(因为lcp是排序后两后缀中间height最小值),然后根据每次入栈种类来给答案算贡献 #include<iostream> #include<cstdio> #include<cstring> using namespace st…
[NOI2015]品酒大会 题目描述 一年一度的"幻影阁夏日品酒大会"隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发"首席品酒家"和"首席猎手"两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 n 杯鸡尾酒.这 n 杯鸡尾酒排成一行,其中第 n 杯酒 (1 ≤ i ≤ n) 被贴上了一个标签si,每个标签都是 26 个小写 英文字母之一.设 str(l, r)表示第 l 杯酒到第 r 杯酒的 r −…
补博客! 首先我们观察题目中给的那个求\(ans\)的方法,其实前两项没什么用处,直接\(for\)一遍就求得了 for (int i=1;i<=n;i++) ans=ans+i*(n-1); 那么我们考虑剩下的部分应该怎么求解! 首先这里有一个性质.对于任意两个后缀\(i,j\),他们的\(lcp\)长度是他们对应的\(rank\)之间的\(height\)的\(min\) (左开右闭) 或者这样说 \(lcp(i,j) = min(height[rank[i]+1],height[rank[…
这道是求长度不小于 k 的公共子串的个数...很不幸,我又TLE了... 解法参考论文以及下面的链接 http://www.cnblogs.com/vongang/archive/2012/11/20/2778481.html http://hi.baidu.com/fpkelejggfbfimd/item/5c76cfcba28fba26e90f2ea6 ; var c,h,rank,sa,x,y,stack:..maxn] of longint; n,k,top:longint; a,b,d…