codeforces 802I. Fake News (hard) 后缀数组

题意:求一个串中,所有本质不同子串的出现次数的平方和。

题解:

对于只出现一次的串的贡献, SA[i]与 SA[i−1]、SA[i] 与 SA[i+1]的LCP的max表示这个串的前max个是不止出现一次,所以该串的长度−max就是只出现一次的串的个数,for一遍,求出每个sa[i]对应的贡献加起来即可

对于出现多次的串的贡献。

对于i,l[i]表示左边第一个数使height[l[i]]

我们用单调栈来维护一个 height 升序的单调栈st,st[now]记录height值,pos[now]记录相应的位置.

做过一些后缀数组+单调栈的题,过程看代码应该很好理解。

#include
using namespace std;
typedef long long ll;
const int N=2e5+10,inf=0x3f3f3f3f;
int sa[N];
int rk[N];
int tmp[N];
int lcp[N];
char s[N],t[N];
int n,k;
bool cmp(int i,int j){
    if(rk[i] != rk[j]) return rk[i]0&&st[now]>len){
                ll v1=st[now]-max(st[now-1],len);
                ll v2=i-pos[now]+1;
                ans+=v1*v2*v2;
                newpos=pos[now--];
            }
            st[++now]=len;
            pos[now]=newpos;
        }

        for(int i=0;i

 

你可能感兴趣的:(后缀数组)