SDOI2016 生成魔咒

2022-05-08 04:18:09 字數 1659 閱讀 1143

魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 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,1,1] 三種。最初 s 為空串。共進行 n 次操作,每次操作是在 s 的結尾加入乙個魔咒字元。每次操作後都 需要求出,當前的魔咒串 s 共有多少種生成魔咒。

第一行乙個整數 n。 

第二行 n 個數,第 i 個數表示第 i 次操作加入的魔咒字元。 

1≤n≤100000。,用來表示魔咒字元的數字 x 滿足 1≤x≤10^9

輸出 n 行,每行乙個數。第 i 行的數表示第 i 次操作後 s 的生成魔咒數量

7 1 2 3 3 3 1 2

1 3 

6 9 

12 17 

22資料約束: 

對於 10% 的資料,1≤n≤10。 

對於 30% 的資料,1≤n≤100。 

對於 60% 的資料,1≤n≤1000。 

對於 100% 的資料,1≤n≤100000。 

用來表示魔咒字元的數字 x 滿足 1≤x≤109。

反過來後,每多乙個原來的字首,相當於多乙個現在的字尾.

注意到乙個事(tao)實(lu).

每次新加入的那個字尾與前面加的字尾的lcp一定是前面名次與他最相近的兩個字尾與他的lcp的最大值,

因為名次越近相似度越高.

所以維護乙個set和st表,每次求出這個值,最終產生的答案就是這個字尾的長度-lcp.

1 #include2 #include3 #include4 #include5 #include

6 #include7 #include8 #include9 #include10 #include11 #include12 #include

13 #include14

#define ll long long

15#define maxn 100010

16using

namespace

std;

17int

s[maxn],sa[maxn],rk[maxn],tmp[maxn],n,k;

18 ll lcp[maxn],ans[maxn],f[maxn][21

];19

setse;

20bool cmp(int i,int

j)26}27

void

get_sa()38}

39void

get_lcp()49}

50int

main()

74if((++it)!=se.end())

79 ans[i]=n-i-max(lcpa,lcpb);80}

81for(int i=n-1;i>=0;i--)

82 ans[i]+=ans[i+1],printf("

%lld\n

",ans[i]);

83return0;

84 }

SDOI2016 生成魔咒

這是一道 sa 的練手好題 建議做之前先去做一下2408 之後你就肯定會做這道題了 首先上面那道題的答案就是 sum nn 1 sa i het i 就是對於每乙個字尾求出其能產生的子串,之後減掉和之前本質相同的子串 對於這個題,我們需要求出所有字首的本質不同的子串個數 先無腦敲上 sa 和 het...

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...

SDOI2016 生成魔咒(字尾自動機)

看一眼題。本質不同的字串數。嘴角微微上揚。每一次加乙個數輸出乙個答案。笑容漸漸消失。等等,sam 好像也可以求本質不同的字串。設當前字串用 x 表示,每次插入完成後 ans 加上 len x len fa 就行了。嘴角微微上揚。等等,炸空間了。笑容漸漸消失。用 map 不就得了。嘴角再次上揚。寫完過...