題目描述
給定一顆 nnn 個節點的無根樹,每條邊上附有乙個小寫英文本母。
於是一條路徑對應乙個字串。
一共有 qqq 次詢問,每次詢問以節點 uuu 為起點的非空字串中有多少字典序嚴格小於字串 u⇝vu \leadsto vu⇝v 。
輸入格式
第一行,兩個個整數 n,qn, qn,q。
接下來 n−1n - 1n−1 行,每行兩個整數,乙個小寫字母。 u,v,cu, v, cu,v,c。 表示存在字母為 ccc 的樹邊 (u,v)(u, v)(u,v)。保證 u≠vu \neq vu≠v。
接下來 qqq 行,每行兩個整數 u,vu, vu,v。
輸出格式
qqq 行,每行乙個答案。
樣例 樣例輸入 1
4 3
4 1 t
3 2 p
1 2 s
3 2
1 3
2 1
樣例輸出 1
0 1
1 樣例解釋 1
第乙個詢問,以 333 為起點的字串有p,ps,pst。3⇝23\leadsto 23⇝2 生成p。沒有比p字典序嚴格小的字串。
第二個詢問,以 111 為起點的字串有s,sp,t。1⇝31\leadsto 31⇝3 生成sp。s字典序比sp小。
第二個詢問,以 222 為起點的字串有p,s,st。2⇝12\leadsto 12⇝1 生成s。p字典序比s小。
樣例輸入 2
8 4
4 6 p
3 7 o
7 8 p
4 5 d
1 3 o
4 3 p
3 2 e
8 6
3 7
8 1
4 3
樣例輸出 2
6 1
3 1
資料範圍與提示
n≤4000,q≤50000n\le 4000, q \le 50000n≤4000,q≤50000
這道題和普通字典樹不一樣 字母存在邊上而不是點上。。。不過其實沒啥差別。
這道題難點在於如何統計嚴格小於 uv所得字串的 的字串數量
其實可以發現乙個串比別的嚴格大的有三種情況:
1.和它長度相等的但是最後字母比它大。
2.比它長度小 但是有個字母比它大
3.比它長度大,但是前面有個字母比它大
所以如何統計呢
首先在每乙個節點 建立一棵trie樹
然後用sum陣列乙個個往前統計,因為trie樹的性質,所以可以相當於把前面得所有字母都固定住,就是前面每個字母都和該比較串的一模一樣。然後不斷統計,從葉子節點把數量加上父節點,一層層加上去,最後加到根上,因為如果一層的a 字母比同一層的b字母大,那麼就可以加上所有比<=b字母的串的數量,貼**。然後最後還有統計上前面和它相等串的數量,直接統計tire樹的點的cnt即可,因為「abcd」>」abc」,而sum 只能統計出 「abc」>」abb」 和」abc」>」abbc」這種型別的情況 加起來就是所有完整的情況。另外根節點從0開始,根節點是空串,所以加了1,輸出答案時減1即可
其實就相當於 sum是從後處理到前面比它小的,而get_answer 是把前面比它小統計到真正的串的後面。因為sum就相當於把前面固定住了,實際上前面也有比它小的情況。。。
#include
using
namespace
std;
struct node
tr[4010];
int n,q;
vector
v[4010];
vector
ch[4010];
int ans[4010][4010];
int m;
void build(int x,int y,int p)
build(v[x][i],x,tr[p].son[c]);
}}void get_answer(int x,int y,int p,int cnt,int ans)
}int main()
for(int i=1;i<=n;i++)}}
get_answer(i,0,0,0,ans[i]);
}while(q--)
}
C 字典樹 字母樹 的模板
儲存一下jimliu大神的 既然jimliu大神的這個.net部落格不維護了。我就搬過來了。哈哈哈 希望jimliu大神不要見怪。泛型字母樹,忽略大小寫 泛型型別 public class trietree 建立字母樹結點 該結點的元素 public trienode t elem endregio...
字典樹 統計難題
描述 ignatius最近遇到乙個難題,老師交給他很多單詞 只有小寫字母組成,不會有重複的單詞出現,現在老師要他統計出以某個字串為字首的單詞數量 單詞本身也是自己的字首 輸入輸入資料的第一部分是一張單詞表 不超過15000個 每行乙個單詞,單詞的長度不超過10,它們代表的是老師交給ignatius統...
字典樹 統計難題
ignatius最近遇到乙個難題,老師交給他很多單詞 只有小寫字母組成,不會有重複的單詞出現 現在老師要他統計出以某個字串為字首的單詞數量 單詞本身也是自己的字首 input輸入資料的第一部分是一張單詞表,每行乙個單詞,單詞的長度不超過10,它們代表的是老師交給ignatius統計的單詞,乙個空行代...