BJWC2018 Border 的四種求法

2022-05-08 05:54:09 字數 2199 閱讀 2592

luogu

給乙個小寫字母字串\(s\),\(q\)次詢問每次給出\(l,r\),求\(s[l..r]\)的\(border\)。

我們考慮轉化題面:給定\(l,r\),求滿足\(lcs(i,r)\ge i-l+1\)的最大的\(i\)。

對於\(lcs(i,r)\),考慮對\(s\)構建\(sam\),那麼我們知道\(lcs\)的可能取值就是從字尾\(r\)所代表的節點沿著\(fail\)樹到根節點的路徑上節點的\(len\)的取值。

那麼我們得到了乙個暴力做法:\(sam\)+線段樹合併後暴跳\(fail\)樹,

在每個節點的線段樹中查詢\([l,min(r,len+l-1))\)中最大的\(i\)。

如何優化?

考慮樹鏈剖分,我們要求出的一條根到父親的鏈在\(fail\)樹上是若干段重鏈的字首。

那麼可以對每條重鏈進行離線而分開考慮。

查詢字首時,除了最後乙個點需要查詢重兒子及其子樹,其餘的點都只要查詢輕兒子及其子樹即可。

因此查詢字首時對於最後乙個點仍然使用\(sam\)+線段樹合併的做法,

對於其他的點,考慮將\(lcs(i,r)\ge i-l+1\)變為\(i-len[x]+1\le l\)

只須從上往下乙個個插入輕子樹的兒子+回答詢問。

回答詢問時,需要建立一棵以\(i\)為下標,權值為\(i-len[x]+1\)的最小值線段樹,

查詢時需要查詢\(l\le i且\(i-len[x]+1\le l\)的最大的\(i\),

此時線段樹上二分,根據右子樹的最小值是否\(\le l\)作出決策,單次時間複雜度降為\(o(logn)\)。

由於每個點到根節點的輕邊僅\(o(log)\)條,因此插入的總時間複雜度為\(o(nlog^2n)\)。

線段樹處理詢問的總時間同樣為\(o(nlog^2n)\)。

故總時間複雜度為\(o(nlog^2n)\)。

話說這是我第一次寫sam+線段樹合併

我錯了是我人醜常數大1e5還要跑300ms

#include#define pb push_back

#define mp make_pair

#define fi first

#define se second

#define fl "a"

using namespace std;

typedef unsigned long long ll;

typedef pairpi;

typedef vectorvi;

typedef long double dd;

const int n=4e5+10;

const int mod=1e9+7;

const int inf=2147483647;

inline ll read()

inline void file()

#define ls (i<<1)

#define rs (i<<1|1)

#define mid ((l+r)>>1)

struct node;

int n,q;char s[n];vectorq[n];int ans[n];

int head[n],nxt[n],to[n],cnt;

inline void add(int u,int v)

int lst=1,tot=1,cnts=0,len[n],fa[n],tr[n][26],pos[n],fid[n];

inline void extend(int c)

} lst=cur;pos[lst]=++cnts;fid[cnts]=lst;

}namespace s1

int merge(int a,int b)

int query(int i,int l,int r,int x,int y)

int query(int i,int l,int r,int x,int y,int v)

for(int i=0,sz=q[u].size(),l,r,id,res;i} for(int k=0,u;k} for(int k=0,u;k}}

inline void init()

inline void solve()),u=fa[top[u]];

} getans(1);

for(int i=1;i<=q;i++)printf("%d\n",ans[i]);

}int main()

BJWC2018 最長上公升子串行

description 現在有乙個長度為n的隨機排列,求它的最長上公升子串行長度的期望。為了避免精度誤差,你只需要輸出答案模998244353的餘數。input 輸入只包含乙個正整數n。n 28 output 輸出只包含乙個非負整數,表示答案模998244353的餘數。可以證明,答案一定為有理數,設...

BJWC2008 雷濤的小貓

嘟嘟嘟 dp。剛開始我想的是dp i j 表示在第 i 棵樹上,高度為h能吃到的最多的果子,如此能得到轉移方程 dp i j max dp i j 1 dp k j derta k 1 n k i 但因為這樣寫會導致dp k j derta k i 的部分沒有更新,所以應該把dp試的兩胃交換一下。這...

css中的border屬性。。。。。

1.border color 邊框的顏色 一般設定邊框都有3個屬性 寬度 線的樣式 顏色,如果寬度設定了很多px,那麼就可以給邊框設定很多顏色,讓邊框顯示出漸變的效果,不過設定邊框不同顏色時只能通過border bottom colors,border top colors,border left ...