BZOJ 4516 Sdoi2016 生成魔咒

2022-04-30 03:09:08 字數 1661 閱讀 4548

bzoj_4516_[sdoi2016]生成魔咒_字尾陣列+st表+splay

魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 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 的生成魔咒數量

71 2 3 3 3 1 213

691217

22在後面新增字元每次會產生若干個字尾。於是翻轉一下相當於每次只新增乙個字尾。

然後如何求不同的子串個數呢?

首先對於乙個字尾$suffix(i)$,會貢獻$n-i+1$個子串,但這些子串會有一些重複的,於是找$rank[i]$的前驅和後繼所在的字尾設為$j$。

那麼會有$lcp(suffix(i),suffix(j))$這麼多是重複的。

於是用splay維護前驅後繼,然後st表求兩個字尾的lcp。

**:

#include #include #include using namespace std;

#define n 100050

#define ls ch[p][0]

#define rs ch[p][1]

#define get(x) (ch[f[x]][1]==x)

typedef long long ll;

int n,ws[n],wv[n],wa[n],wb[n],rank[n],sa[n],height[n],r[n];

int f[n],ch[n][2],siz[n],rt,val[n],reimu;

//////////////////////////////////////////////

struct a a[n];

bool cmp1(const a &x,const a &y)

splay(l,0); splay(r,rt);

ch[r][0]=newnode(x);

f[reimu]=r; pushup(r); pushup(l);

}int pre(int x)

return val[ans];

}int nxt(int x)

return val[ans];

}/////////////////////////////////////////

struct st

for(j=1;(1<=0;i--)

int nx=nxt(rank[i]);

if(nx<=n)

ans-=tmp;

insert(rank[i]);

printf("%lld\n",ans);

}}/*

71 2 3 3 3 1 2

*/

bzoj4516 SDOI2016 生成魔咒

time limit 10 sec memory limit 128 mb submit 376 solved 232 submit status discuss 魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1 2 拼湊起來形成乙個魔咒串 1,2 乙個魔咒串 s 的非空字串...

bzoj4516 Sdoi2016 生成魔咒

4516 sdoi2016 生成魔咒 time limit 10 sec memory limit 128 mb submit 575 solved 327 submit status discuss 魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1 2 拼湊起來形成乙個魔咒...

bzoj 4516 Sdoi2016 生成魔咒

time limit 10 sec memory limit 128 mb submit 1026 solved 576 submit status discuss 魔咒串由許多魔咒字元組成,魔咒字元可以用數字表示。例如可以將魔咒字元 1 2 拼湊起來形成乙個魔咒串 1,2 乙個魔咒串 s 的非空字...