51nod1464(trie + dfs)

Posted ygeloutingyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod1464(trie + dfs)相关的知识,希望对你有一定的参考价值。

题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1464

 

题意: 中文题诶~

 

思路: 将所有半回文串构建成一棵字典树, 再 dfs 里面字典序第 k 大的字符串.

注意插入半回文串时不能完全暴力插入, 不然插入的时间复杂度为 O(n^3), 会 tle. 可以先用 dp 预处理一下, dp[i][j] 存储 子串[i, j] 是否为回文串, vis[i] 记录以 i 开头的最长半回文串末尾位置. 那么插入时可以每次插入 [i, vis[i]] 之间的所有半回文串, 时间复杂度为 O(n^2). 然后再 dfs 一下答案即可.

 

代码:

技术分享
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 using namespace std;
 5 
 6 const int MAXN = 5e3 + 10;
 7 int trie[MAXN * MAXN][2], num[MAXN * MAXN], id = 1;
 8 bool dp[MAXN][MAXN];//dp[i][j]存储[i,j] 是否为半回文串
 9 int vis[MAXN];//vis[i]存储以i开始的最长半回文串末尾位置
10 char s[MAXN];
11 
12 void init(int len){
13     for(int i = len - 1; i >= 0; i--){
14         vis[i] = i;
15         dp[i][i] = true;
16         for(int j = i + 1; j < len; j++){
17             if(s[i] == s[j]){
18                 if(i + 2 >= j - 2) dp[i][j] = true;
19                 else dp[i][j] = dp[i + 2][j - 2];
20             }
21             if(dp[i][j]) vis[i] = j;
22         }
23     }
24 }
25 
26 void insert(int st){
27     int node = 0;
28     for(int i = st; i <= vis[st]; i++){
29         int cnt = s[i] - a;
30         if(!trie[node][cnt]) trie[node][cnt] = id++;
31         if(dp[st][i]) num[trie[node][cnt]]++;
32         node = trie[node][cnt];
33     }
34 }
35 
36 int k;
37 string sol;
38 
39 void dfs(int x){
40     string cnt = sol;
41     if(k > 0 && trie[x][0]){
42         sol += a;
43         k -= num[trie[x][0]];
44         dfs(trie[x][0]);
45     }
46     if(k > 0 && trie[x][1]){
47         sol = cnt;
48         sol += b;
49         k -= num[trie[x][1]];
50         dfs(trie[x][1]);
51     }
52 }
53 
54 int main(void){
55     scanf("%s%d", s, &k);
56     int len = strlen(s);
57     init(len);
58     for(int i = 0; i < len; i++){
59         insert(i);
60     }
61     dfs(0);
62     cout << sol << endl;
63     return 0;
64 }
View Code

 

以上是关于51nod1464(trie + dfs)的主要内容,如果未能解决你的问题,请参考以下文章

51Nod1601 完全图的最小生成树计数 Trie Pruffer编码

51nod 1295 XOR key (可持久化Trie树)

51nod1489(dfs)

51Nod - 1295:XOR key (可持久化Trie求区间最大异或)

51nod 1405 树的距离之和(dfs)

51Nod 1405 树的距离之和 (dfs)