一道sam練習題

2021-10-02 06:18:12 字數 2928 閱讀 9601

考慮答案實際上是每個子串的出現次數的平方和.

這個可以通過手玩樣例驗證.

考慮廣義sam:先將所有字串建成trie,然後再在trie上bfs,建出sam.

考慮fail樹

每次插入乙個新節點,會改變從這個節點開始到根的路徑上的每個節點的right集合大小.

所以考慮樹剖維護這種操作,然後每乙個單詞的答案就是之前所有單詞的答案,再計算自己的答案,然後注意這裡乙個線段樹節點維護的有sam上這段區間總共的本質不同子串數量,要求的答案和修改標記

#include

using

namespace std;

const

int maxn=

1e6+5;

int n,m;

long

long ans;

int s[maxn]

;int tot,trie[maxn][26

],ch[maxn][26

],len[maxn]

,sz[maxn]

,en[maxn]

,fa[maxn]

;vector<

int> e[maxn]

;int son[maxn]

,last[maxn]

,fail[maxn]

;inline

void

insert

(int c,

int ed)

else}}

void

bfs()}

}}void

dfs1

(int u)

}int top[maxn]

,dfn[maxn]

,tim;

void

dfs2

(int u,

int tp)

for(

int i=

0;i.size()

;i++)}

struct nodet[maxn<<2]

;#define ls rt<<1

#define rs rt<<1|1

inline

void

pushup

(int rt)

void

build

(int rt,

int l,

int r,

int x,

int y)

int mid=

(l+r)

>>1;

if(x<=mid)

build

(ls,l,mid,x,y)

;else

build

(rs,mid+

1,r,x,y)

; t[rt]

.v=t[ls]

.v+t[rs]

.v;}

void

pushdown

(int rt)

}void

ins(

int rt,

int l,

int r,

int x,

int y)

int mid=

(l+r)

>>1;

pushdown

(rt);if

(x<=mid)

ins(ls,l,mid,x,y);if

(y>mid)

ins(rs,mid+

1,r,x,y)

;pushup

(rt);}

void

get(

int rt,

int l,

int r,

int x,

int y)

pushdown

(rt)

;int mid=

(l+r)

>>1;

if(x<=mid)

get(ls,l,mid,x,y);if

(y>mid)

get(rs,mid+

1,r,x,y);}

void

calc

(int x)

}void

change

(int x)

}signed

main()

}//printf("%lld\n",tot);

//return 0;

last[1]

=1;tot=1;

bfs();

//printf("%lld\n",tot);

m=tot;tot=0;

for(

int i=

2;i<=m;i++

)e[fail[i]].

push_back

(i);

tot=0;

dfs1(1

);son[1]

=0;dfs2(1

,0);

for(

int i=

1;i<=m;i++

)//return 0;

for(

int i=

1;i<=n;i++

) x=1;

for(

int j=en[i-1]

+1;j<=en[i]

;j++

) x=1;

for(

int j=en[i-1]

+1;j<=en[i]

;j++

)printf

("%lld\n"

,ans);}

return0;

}

一道互動練習題

的做法 考慮逐位確定 對於每個位置,往後列舉有沒有位置可以使得正確位置更多,如果有,那麼有兩種情況,1是這個位置被放到了正確的位置,2是這個位置本來應該放的數被放來了 這裡的重點是我們需要區分1和2 具體的做法是記下讓這個位置答案正確位置數變大的2個位置,將其和i一起移位 這裡是手繪示意圖.即把p1...

一道fft練習題

考場上想到的o n 2 o n 2 o n2 暴力 記f i j f i j f i j 表示前i個位置,長度為j的連擊出現的期望次數 記g i j g i j g i j 表示第到i個位置為止,目前連擊次數為j的概率 轉移時有一些細節 include using namespace std con...

一道線段樹練習題

e9首先我們有乙個考慮列舉每個mex,計算其貢獻的想法.即有多少個區間的mex mexme x是我們當前列舉的這個值.然後我們手畫一下圖,可以發現,乙個數如果想要成為乙個區間的mex mexme x,必須要這個區間已經出現了所有比它小的數.所以可以從小到大列舉mex mexme x,然後用r rr陣...