# BZOJ3879:SvT(后缀数组,单调栈,ST表)

## Description

(我并不想告诉你题目名字是什么鬼)

7 3
popoqqq
1 4
2 3 5
4 1 2 5 6

0
0
2
Hint

## Solution

$vector$去重的时候不能

## Code

  1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<vector>
5 #include<algorithm>
6 #define N (500009)
7 #define LL long long
8 #define MOD (23333333333333333LL)
9 using namespace std;
10
11 int n,m=120,q,t,L[N],R[N],stack[N],top;
12 int wt[N],wa[N],wb[N];
13 int SA[N],Rank[N],Height[N];
14 int LOG2[N],ST[N][21];
15 char r[N];
16 vector<int>v,w;
17
19 {
20     int x=0,w=1; char c=getchar();
21     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
22     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
23     return x*w;
24 }
25
26 bool cmp(int *y,int a,int b,int k)
27 {
28     int arank1=y[a];
29     int brank1=y[b];
30     int arank2=a+k>=n?-1:y[a+k];
31     int brank2=b+k>=n?-1:y[b+k];
32     return arank1==brank1 && arank2==brank2;
33 }
34
35 void Build_SA()
36 {
37     int *x=wa,*y=wb;
38     for (int i=0; i<m; ++i) wt[i]=0;
39     for (int i=0; i<n; ++i) wt[x[i]=r[i]]++;
40     for (int i=1; i<m; ++i) wt[i]+=wt[i-1];
41     for (int i=n-1; i>=0; --i) SA[--wt[x[i]]]=i;
42
43     for (int j=1; j<=n; j<<=1)
44     {
45         int p=0;
46         for (int i=n-j; i<n; ++i) y[p++]=i;
47         for (int i=0; i<n; ++i) if (SA[i]>=j) y[p++]=SA[i]-j;
48
49         for (int i=0; i<m; ++i) wt[i]=0;
50         for (int i=0; i<n; ++i) wt[x[y[i]]]++;
51         for (int i=1; i<m; ++i) wt[i]+=wt[i-1];
52         for (int i=n-1; i>=0; --i) SA[--wt[x[y[i]]]]=y[i];
53
54         m=1; swap(x,y);
55         x[SA[0]]=0;
56         for (int i=1; i<n; ++i)
57             x[SA[i]]=cmp(y,SA[i],SA[i-1],j)?m-1:m++;
58         if (m>=n) break;
59     }
60 }
61
62 void Build_Height()
63 {
64     for (int i=0; i<n; ++i) Rank[SA[i]]=i;
65     int k=0; Height[0]=0;
66     for (int i=0; i<n; ++i)
67     {
68         if (!Rank[i]) continue;
69         if (k) k--;
70         int j=SA[Rank[i]-1];
71         while (r[i+k]==r[j+k]) k++;
72         Height[Rank[i]]=k;
73     }
74 }
75
76 void Build_ST()
77 {
78     int t=0;
79     for(int i=2;i<=n;i++) LOG2[i]=LOG2[i>>1]+1;
80     for (int i=0; i<n; ++i) ST[i][0]=Height[i];
81     for (int j=1; j<=20; ++j)
82         for (int i=0; i+(1<<j)-1<n; ++i)
83             ST[i][j]=min(ST[i][j-1],ST[i+(1<<j-1)][j-1]);
84 }
85
86 int Query(int l,int r)
87 {
88     int k=LOG2[r-l+1];
89     return min(ST[l][k],ST[r-(1<<k)+1][k]);
90 }
91
92 bool cmp1(int a,int b)
93 {
94     return Rank[a]<Rank[b];
95 }
96
97 int main()
98 {
100     Build_SA(); Build_Height(); Build_ST();
101     while (q--)
102     {
103         v.clear(); w.clear();
105         for (int i=1; i<=t; ++i) v.push_back(read()-1);
106         sort(v.begin(),v.end());
107         v.erase(unique(v.begin(),v.end()), v.end());
108         sort(v.begin(),v.end(),cmp1);
109         w.push_back(-1);
110         for (int i=1; i<v.size(); ++i)
111             w.push_back(Query(Rank[v[i-1]]+1,Rank[v[i]]));
112         w.push_back(-1);
113         int ws=w.size();
114         stack[top=1]=0;
115         for (int i=1; i<ws-1; ++i)
116         {
117             while (top && w[stack[top]]>w[i]) top--;
118             L[i]=stack[top]; stack[++top]=i;
119         }
120         stack[top=1]=ws-1;
121         for (int i=ws-2; i>=1; --i)
122         {
123             while (top && w[stack[top]]>=w[i]) top--;
124             R[i]=stack[top]; stack[++top]=i;
125         }
126         LL ans=0;
127         for (int i=1; i<ws-1; ++i) (ans+=1ll*(i-L[i])*(R[i]-i)%MOD*w[i]%MOD)%MOD;
128         printf("%lld\n",ans);
129     }
130 }
posted @ 2019-02-17 19:07  Refun  阅读(158)  评论(0编辑  收藏  举报