樹上的回文

2021-08-19 04:20:12 字數 2012 閱讀 5424

羅馬種了一棵樹,樹上有n個點。每個點有乙個小寫英文本母。1號點是樹的根,剩下的n-1個點都有乙個父親。點和父親之間通過乙個邊相連。第i個點的父親是pi,且pi乙個點的深度是從根到當前點的路徑上經過的點數。根的深度是1。

u在v的子樹中,當且僅當u往根方向走可以到達v。特別的,v也是在v的子樹中。

羅馬給你m個查詢,第i個查詢包含兩個整數vi,hi。現在收集在vi子樹中且深度是hi的結點。判斷一下把這些結點重新排列是否能組成乙個回文。

樣例解釋:

乙個字串s是回文,當且僅當他正著讀和反著讀是一樣的。空串也是回文。

第一查詢中,點1包含z,可以構成回文。

第二個查詢中點5和6包含c,d,這個不能組成回文。

第三個查詢中,沒有點是深度4的,組成乙個空串。

第四個查詢中,也是構成了乙個空串。

第五個查詢中,2,3,4符合查詢條件,包含字母a,c,c。可以構成cac。

input

單組測試資料。

第一行包含兩個n, m (1≤n,m≤500000),表示樹的結點數目和查詢數目。

第二行有n-1個數字 p2,p3,...,pn ,表示每乙個點的父親。(1≤pioutput

對於每乙個查詢,如果能夠組成回文,輸出yes,否則輸出no。

input示例

6 5

1 1 1 3 3

zacccd

1 13 3

4 16 1

1 2

output示例

yes

noyes

yes

yes

#include #include #include #include #include using namespace std;

const int maxn = 5e5 + 10;

struct node

int index;

int height;

};int n, m;

vectorchild[maxn];

vectorbuf[maxn];

char val[maxn];

void dfs(vector&parent, int pos, int h)

for (int i = 0; i < child[pos].size(); i++)

parent.pop_back();

}char num[26];

bool valid()

}if (count > 1)

return true;

}bool cmp(const node a, const node b)

int leftmost(vector&a, int h)

else

}if (a[left].height == h)

else if (a[right].height == h)

return -1;

}int rightmost(vector&a, int h)

else

}if (a[right].height == h)

else if (a[left].height == h)

return -1;

}template inline void scan_d(t &ret)

}int main()

scanf("%s", &val[1]);

vectorparent;

dfs(parent, 1, 0);

for (int i = 1; i <= n; i++)

int v, h;

for (int i = 0; i < m; i++)

int right = rightmost(buf[v], h);

memset(num, 0, sizeof(num));

for (int j = left; j <= right; j++)

if (valid())

else

}return 0;

}

題解 yww 與樹上的回文串

題目鏈結 題意複述 給一棵樹,每條邊上有乙個字元 0 或 1 求有多少對 x,y x,滿足 x 到 y 路徑上的邊上的字元按順序組成的字串為回文串。又一道神仙題啊 用其它方法並不能方便地求出答案,考慮點分。經過乙個點的回文串只有兩種情況 先找出以重心為開頭的所有路徑所表示的字串,考慮第一種情況 可以...

BZOJ2342 雙倍回文(回文自動機 樹上差分)

題面 題意 給你乙個串,求出它的最長子串 滿足該子串有兩個長度相等且為偶數的回文串拼接而成 該串顯然是回文串,就對應回文自動機上的乙個狀態 若某個狀態的長度為4的倍數 且存在某個祖先的長度為其一半 則該狀態可以貢獻答案 因為祖先即回文字尾和字首 長度為其一半的字首和字尾都是回文串 顯然符合題意 我的...

樹上直徑 樹上最遠點O n

題目大意 對於一棵n個結點的無根樹,求出每個結點的最遠點,要求時間複雜度為o n 對於乙個點,距離它最遠的點一定是直徑的端點。證明 我們求直徑的時候,兩次dfs。兩次bfs 或者dfs 方法 先從任意一點p出發,找離它最遠的點q,再從點q出發,找離它最遠的點w,w到q的距離就是是的直徑 若p已經在直...