求出字尾陣列和height陣列後,從大到小掃相似度進行合併,每次相當於合併兩個緊挨著的區間。
合併區間可以用並查集來實現,每個區間的資訊都記錄在這個區間的並查集的根上,合併並查集時用乙個根的資訊更新另乙個根的資訊同時計算兩個答案。
時間複雜度\(o(n\log n)\)。
#include#include#includeusing namespace std;
typedef long long ll;
const int n = 300003;
ll ret1 = 0, ret2 = -1000000000000000001ll;
int t1[n << 1], t2[n << 1], c[n];
void st(int *x, int *y, int *sa, int n, int m)
void mkhz(int *r, int *sa, int n, int m)
}void mkh(int *r, int *sa, int *rank, int *h, int n)
char s[n];
int r[n], n, rank[n], sa[n], a[n], h[n], id[n], fa[n], num_max[n], num_min[n], sz[n];
ll ans1[n], ans2[n];
bool cmp(int x, int y)
int find(int x)
template void check_max(t &x, t y)
template void check_min(t &x, t y)
void merge(int x, int y)
int main()
for (int i = 0; i < n; ++i) printf("%lld %lld\n", ans1[i], ans2[i]);
return 0;
}
UOJ 131 NOI2015 品酒大會
題鏈 題解 網上大多數的方法都是用並查集維護。這裡呢,給出另一種自己yy的解法 但實際上本質差不多吧 字尾陣列,rmq,單調棧 1 預處理 1 首先對字串字尾排序,得到 sa i rank i height i 2 然後維護出 l i 表示在字尾陣列中,排名最小 記其排名為 l i 的字尾與排名為 ...
uoj131 NOI2015 品酒大會
題目鏈結 很容易想到p和q r相似 就等價於在字尾陣列中q與p之間的height值 ge r 也就是說 的那些height值會把排好序後的字尾分割成若干段,可以想到倒序列舉r,每當r減小1時,中間把他們分開的那些 屏障 就會減少一些,兩邊的集合會合併到一起,現在的問題就是給定乙個集合,支援合併操作,...
UOJ131 NOI2015 品酒大會
考前掙扎 bu shi 之前留下來的坑 首先注意到sam的parent樹 是反串的字尾樹 也就是原串的字首樹 這個性質很重要 所以說我們在樹上統計的時候兩個點的lca就是兩個字尾串的lcp 於是可以替代字尾陣列 嘿嘿嘿 然後嘞我們樹形dp 統計的size就是以這個串為字首的子串個數 然後我們通過差分...