P4070 SDOI2016 生成魔咒 解題報告

2021-10-19 09:27:26 字數 2322 閱讀 5096

link

一開始給乙個空串 s

ss,每次在其最後加入乙個字元 x

xx,詢問每次加入後 s

ss 的本質不同的非空子串的個數。

∣ s∣

≤105

,1≤x

≤109

.|s|\le 10^5, 1\le x\le 10^9.

∣s∣≤10

5,1≤

x≤10

9.具體地說,加入乙個字元 x

xx 得到的貢獻就為 len

(np)

−len

(fa(

np))

len(np)-len(fa(np))

len(np

)−le

n(fa

(np)

)。那麼這題就做完了。

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

char in[

1<<20]

,*ss = in,

*tt = in;

#define getchar() (ss == tt && (tt = (ss = in) + fread(in, 1, 1 << 20, stdin), ss == tt) ? eof : *ss++)

ll read()

const

int maxn =

2e5+5;

int n, lst =

1, tot =1;

ll ans;

struct nodee[maxn]

;void

ins(

int c)}}

intmain()

return0;

}

我們每次加入乙個字元,所有的字尾都會發生變化。於是我們不妨倒轉這個串,改為在之前新增字元,這樣每次就只增加乙個字尾。

不妨把新增變成刪除,考慮每次刪除頭乙個字元的貢獻。不難發現,貢獻為 n−i

+1

−max

⁡n-i+1-\max\(\mathrm(i)),\mathrm(\mathrm(i+1))\}

n−i+1−

max。然後再刪去這個位置,更新 hei

gh

t\mathrm

height

即可。這個操作可以用乙個鍊錶簡單地完成。

#include

#include

#include

using

namespace std;

typedef

long

long ll;

char in[

1<<20]

,*ss = in,

*tt = in;

#define getchar() (ss == tt && (tt = (ss = in) + fread(in, 1, 1 << 20, stdin), ss == tt) ? eof : *ss++)

ll read()

const

int maxn =

2e5+5;

int n;

int s[maxn]

, lsh[maxn]

, lsh_num, sa[maxn]

, rk[maxn]

, ht[maxn]

, x[maxn]

, y[maxn]

, c[maxn]

, nxt[maxn]

, pre[maxn]

;ll ans[maxn]

;void

suffixsort()

}void

getheight()

int j = sa[rk[i]-1

];while

(i+k <= n && j+k <= n && s[i+k]

== s[j+k]

) k++

; ht[rk[i]

]= k;}}

intmain()

for(

int i = n; i >=

1; i--

) ans[i]

+= ans[i+1]

;for

(int i = n; i >=

1; i--

)printf

("%lld\n"

, ans[i]);

return0;

}

P4070 SDOI2016 生成魔咒

魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1 2 拼湊起來形成乙個魔咒串 1,2 乙個魔咒串 s 的非空字串被稱為魔咒串 s 的生成魔咒。例如 s 1,2,1 時,它的生成魔咒有 1 2 1,2 2,1 1,2,1 五種。s 1,1,1 時,它的生成魔咒有 1 1,1 1...

P4070 SDOI2016 生成魔咒(SAM)

題意 一開始有乙個空陣列,n次操作,每次操作都是在陣列的末尾追加乙個數x,要求操作之後輸出陣列中本質不同的子陣列數量。資料範圍 n 1e5,1 x 1e9 解法 本質不同子串容易想到sam,本質不同的子串數量 sum l i l fa i 每次插入乙個新數的時候,設新節點為np,那麼答案累加l np...

LG4070 SDOI2016 生成魔咒

洛谷 sum i.len i.fa.len 那麼產生的貢獻就是 last.len last.fa.len 與 yyb 的對話 q 為什麼構建自動機時中間過程新加的點不會算到最後答案中呢?a 不影響答案啊,你在兩個len之間斷開,對於答案的貢獻不變。include include include in...