暑假集訓每日一題0713(字典樹)

2022-03-06 20:02:33 字數 1112 閱讀 3937

給出n個長度不超過5000的只含數字的字串,你需要回答m次形如i j的詢問,對於每次詢問用一行輸出乙個整數表示第i個字串和第j個字元的最長公共字首的長度。

比如兩個字串分別為201212和201112,"2"、"20"和"201"都是它們的公共字首,但最長的公共字首是"201",於是就應當輸出3。

輸入包含多組測試資料。

每組資料的第一行為乙個整數n(1<=n<=1000),表示一共有n個字串。接下來一共有n行,每行均有乙個長度不超過 5000的只含數字的字串,這n行分別描述了這n個字串。接下來一行有乙個整數m(1<=m<=1000000),表示一共要回答m次詢 問。再接下來一共m行,每行均有兩個正整數i j(1<=i,j<=n),表示你需要回答第i個字串和第j個字串的最長公共字首的長度是多少。

對於每個詢問,用一行輸出乙個整數表示詢問的答案。

2 201212

201112

2 1 1

1 2

6 3

這題可能是我寫的第乙個字典樹的題,當時沒做出來,後來聽了講解才會。

大體思路:在插入字串的時候,記錄字串經過的路徑,可以得到乙個字典樹的結點標號序列,容易證明2個字串的公共字首所經過的結點是一樣的,所以通過二分結點序列來得到2個字串的最長公共字首。

view code

#include #include 

#define min(a,b) ((a)

#define n 1010

#define len 5010

#define node 5000010

intid[n][len];

int e,next[node][11

];int

len[n];

intn,m;

intans[n][n];

void add(int cur,int

k)void

init()

len[i]=j;

}}int f(int i,int

j)

return

min;

}int

main()

while(m--)

}return0;

}

暑假集訓每日一題0712 (線段樹)

維護乙個只有0和1的整數序列,支援以下操作 1 x y v 將區間 x,y 之間的所有整數都變為v v為0或1 2 x y 將區間 x,y 之間所有的1變為0,所有的0變為1 3 x y 查詢區間 x,y 內的1的個數。線段數練習 每段儲存3個關鍵資訊 和,修改標記,反轉標記。需注意的幾點 在更新某...

暑假集訓每日一題0711 (線段樹)

維護乙個整數序列,支援以下操作 1 x v 將第x個整數的值修改為v 2 x y 查詢區間 x,y 之間的最小值 3 x y 查詢區間 x,y 之間的最大值 4 x y 查詢區間 x,y 內的整數和。資料保證查詢結果均在int範圍之內,但中間結果是否可能溢位呢?我交的程式沒考慮這個也ac了。通過這題...

暑假集訓每日一題0717(DFS)

這題是zoj 1008那題。給你n n個方塊,每個方塊被對角線劃分為4部分,每一部分裡面有乙個數字,問能否將方塊拼成乙個邊長為n的大方塊,使得相鄰方塊的相鄰數字相同。用dfs搜尋,需要剪枝,同一層中相同方塊只搜尋一次。view code include include define n 26 def...