bzoj3926 廣義SAM 諸神眷顧的幻想鄉

2021-08-18 10:28:28 字數 2455 閱讀 5922

description

幽香是全幻想鄉里最受人歡迎的萌妹子,這天,是幽香的2600歲生日,無數幽香的粉絲到了幽香家門前的太陽花田上來為幽香慶祝生日。

粉絲們非常熱情,自發組織表演了一系列節目給幽香看。幽香當然也非常高興啦。

這時幽香發現了一件非常有趣的事情,太陽花田有n塊空地。在過去,幽香為了方便,在這n塊空地之間修建了n-1條邊將它們連通起來。也就是說,這n塊空地形成了乙個樹的結構。

有n個粉絲們來到了太陽花田上。為了表達對幽香生日的祝賀,他們選擇了c中顏色的衣服,每種顏色恰好可以用乙個0到c-1之間的整數來表示。並且每個人都站在乙個空地上,每個空地上也只有乙個人。這樣整個太陽花田就花花綠綠了。幽香看到了,感覺也非常開心。

粉絲們策劃的乙個節目是這樣的,選中兩個粉絲a和b(a和b可以相同),然後a所在的空地到b所在的空地的路徑上的粉絲依次跳起來(包括端點),幽香就能看到乙個長度為a到b之間路徑上的所有粉絲的數目(包括a和b)的顏色序列。一開始大家打算讓人一兩個粉絲(注意:a,b和b,a是不同的,他們形成的序列剛好相反,比如紅綠藍和藍綠紅)都來一次,但是有人指出這樣可能會出現一些一模一樣的顏色序列,會導致審美疲勞。

於是他們想要問題,在這個樹上,一共有多少可能的不同的顏色序列(子串)幽香可以看到呢?

太陽花田的結構比較特殊,只與乙個空地相鄰的空地數量不超過20個。

input

第一行兩個正整數n,c。表示空地數量和顏色數量。

第二行有n個0到c-1之間,由空格隔開的整數,依次表示第i塊空地上的粉絲的衣服顏色。(這裡我們按照節點標號從小到大的順序依次給出每塊空地上粉絲的衣服顏色)。

接下來n-1行,每行兩個正整數u,v,表示有一條連線空地u和空地v的邊。

output

一行,輸出乙個整數,表示答案。

sample input

7 3

0 2 1 2 1 0 0

1 23 4

3 54 6

5 72 5

sample output

hint

對於所有資料,1<=n<=100000, 1<=c<=10。

對於15%的資料,n<=2000。

另有5%的資料,所有空地都至多與兩個空地相鄰。

另有5%的資料,除一塊空地與三個空地相鄰外,其他空地都分別至多與兩個空地相鄰。

另有5%的資料,除某兩塊空地與三個空地相鄰外,其他空地都分別至多與兩個空地相鄰

題解

廣義sam裸題

題裡有乙個很有趣的性質:葉子節點不超過20個

我們可以把每個葉子節點都作為根,那麼原樹就變成了一棵「tire」樹(假裝他是吧2333)。由於廣義sam可以識別tire節點到根的所有串。再想想,能走的路徑其實就是葉子節點到樹內任意一點中的子串啦。這時候葉子節點作為tire的根,樹內任意一點作為tire節點。對於這20個tire構建廣義字尾自動機,直接建在一起就可以了

廣義字尾自動機:你就bfs建圖,搜到乙個節點的時候把last設為這個節點的父親,然後跟狹義字尾自動機一樣討論建

最後列舉每個狀態處理一下該狀態下有的子串數即可

#include

#include

#include

#include

#include

using namespace std;

typedef long long ll;

struct sam

tr[4100000];int cnt,root,last;

int add(int

x) }

return np;

}struct node

a[210000];int len,last[110000];

void ins(int

x,int

y)int n,c,col[110000],ru[110000];

struct anode

list[210000];

int head,tail;

bool vis[210000];

void add_sam(int st)

}head++;

}}int main()

root=last=++cnt;

for(int i=1;i<=n;i++)if(ru[i]==1)add_sam(i);

ll ans=0;

for(int i=1;i<=cnt;i++)ans+=(ll)tr[i].dep-tr[tr[i].parent].dep;

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

return

0;}

BZOJ 3926 諸神眷顧的幻想鄉

開始看錯題看成了每個點度數不超過20 後來翻了翻題解原來看錯題的不止我乙個 既然葉子數量不超過20,考慮樹上的任何一條路徑,以任何點為根時,如果它不是一條從上到下的路徑,那麼以它的任意一端的子樹內的某乙個葉子為根必然可以變成從上到下的。否則,以它處於下端的點的子樹內的葉子為根也可以做到。所以如果以每...

BZOJ3926 諸神眷顧的幻想鄉

樹上sam!顯然如果樹上一條一條字串放的話那麼是n 2的w 但是 題目的性質非常吼啊!20個葉子節點 我們就可以 把所有葉子結點拎出來當根 全部扔到乙個sam裡 就吼啦 最後的答案是 因為自動機上乙個節點的貢獻就是這麼多啦 自動機啥的 真的好寫呢 flag 機房好冷啊 附 include inclu...

BZOJ3926 諸神眷顧的幻想鄉(字尾自動機)

bzoj 廣義字尾自動機啦 求多個串的不同子串個數?當然是字尾自動機,最後只要把lo nges t pa rent lon gest 求個和就好啦 那麼這題怎麼建字尾自動機 能夠把所有子串都丟進去呢?當然不用從每乙個節點開始 把樹建出來之後,從每個葉子節點開始遍歷一遍,同時把遍歷到的點查進sa m ...