字首查詢(字典樹 線段樹懶惰標記)

2021-08-19 08:33:09 字數 1404 閱讀 1125

描述 

在乙個 minecraft 村莊中,村長有這一本小寫字母構成的名冊(字串的表),

每個名字旁邊都記錄著這位村民的聲望值,而且有的村民還和別人同名。

隨著時間的推移,因為沒有村民死亡,這個名冊變得十分大。

現在需要您來幫忙維護這個名冊,支援下列 4 種操作:

1. 插入新人名 si,聲望為 ai

2. 給定名字字首 pi 的所有人的聲望值變化 di

3. 查詢名字為 sj 村民們的聲望值的和(因為會有重名的)

4. 查詢名字字首為 pj 的聲望值的和

輸入描述:

第一行為兩個整數 0 ≤ n ≤ 105,表示接下來有 n 個操作;

接下來 n 行,每行輸入乙個操作,行首為乙個整數 1 ≤ oi ≤ 4,表示這一行的操作的種類,

那麼這一行的操作和格式為:

1. 插入人名,這一行的格式為 1 si ai,其中 |ai| ≤ 103

2. 字首修改聲望,這一行的格式為 2 pi di,其中 |di| ≤ 103

3. 查詢名字的聲望和,這一行的格式為 3 sj

4. 查詢字首的聲望和,這一行的格式為 4 pj

輸入保證插入人名的字串的長度和小於或等於 105,總的字串的長度和小於或等於 106。

輸出描述:

對於每一次詢問操作,在一行裡面輸出答案。

示例1輸入

201 a -10

1 abcba -9

1 abcbacd 5

4 a2 a 9

3 aadaa

3 abcbacd

4 a3 a

2 a 10

3 a2 a -2

2 d -8

1 ab -2

2 ab -7

1 aadaa -3

4 a3 abcba

4 a4 c

輸出-14014

13-1911

1110思路:

看到這個,很明顯的字典樹,但是有乙個字首修改,這個只用字典樹實現不了,但是應用了線段樹的懶惰標記就可以了。

除錯了好久,經過不懈努力,終於把這道題給補上了。

**:#include #define ll long long

using namespace std;

const int maxn=110000;

struct node

g[maxn];

int ans,root;

inline int idx(char x)

void pushdown(int u)

g[u].d=0;

}}void inset(char *a,int val)

{ int l=strlen(a);

int u=root;

for(int i=0;i

藍橋杯 演算法訓練 校門外的樹(線段樹 懶惰標記)

演算法訓練 校門外的樹 時間限制 1.0s 記憶體限制 256.0mb 問題描述 某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸0的位置,另一端在l的位置 數 軸上的每個整數點,即0,1,2,l,都種有一棵樹。由於馬路上有一些區域...

查詢字串陣列中最長公共字首

編寫乙個函式來查詢字串陣列中的最長公共字首。如果不存在公共字首,返回空字串 示例 1 輸入 flower flow flight 輸出 fl 示例 2 輸入 dog racecar car 輸出 解釋 輸入不存在公共字首。由於提供的單詞長度不同,應該以長度最短單詞作為基準單詞進行比較,如 flowe...

nyoj685查詢字串(字典樹)

include 685查詢字串 struct trie trie root int turn char c 把字元轉換成陣列序號 void insert char s 插入乙個字串 p p next turn s s p count int tfind char s return p null?0 ...