题目链接

题意:

若一个字符串是半回文串。则满足第一位和最后一位相等, 第三位和倒数第三位相等。如此类推。

给定一个字符串s,输出s的全部子串中的半回文串字典序第k大的 字符串。

good[i][j] 表示 s(i,j) 是半回文串。

把这些回文串插到字典树里 在字典树上找第k个叶子节点。

插入时:插入以i点开头的全部半回文串。

#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <cstdio>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) pt(x / 10);
putchar(x % 10 + '0');
}
typedef int ll;
typedef pair<int, int> pii;
const int inf = 1e9;
const int N = 5005;
bool good[N][N];
#define Word_Len 5050000
#define Sigma_size 2 struct <span class="KSFIND_CLASS_SELECT" id="0KSFindDIV">Trie</span> {
ll ch[Word_Len][Sigma_size], sz; //Word_Len是字典树的节点数 若都是小写字母Sigma_size=26 sz为当前节点数
ll Have_word[Word_Len]; //这个节点下有几个单词
ll val[Word_Len]; // 这个节点附带的信息,初始化为0表示这个节点不存在单词,所以节点带的信息必须!=0
ll pre[Word_Len];
char he[Word_Len];
ll Newnode() { memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = Have_word[sz] = 0; return sz++; }
void init() //初始化字典树
{
sz = 0; Newnode();
}//初始化
ll idx(char c) { return c - 'a'; } //字符串编号 int insert(char *s, int start) { //把v数字加给 s单词最后一个字母
ll u = 0;
for (ll i = 0; s[i]; i++) {
ll c = idx(s[i]);
if (!ch[u][c]) //节点不存在就新建后附加
{
ch[u][c] = Newnode();
he[sz - 1] = s[i];
pre[sz - 1] = u;
}
u = ch[u][c];
if (good[start][start + i]) Have_word[u]++;
}
return u;
}
void dfs(int u) {
val[u] += Have_word[u];
for (int i = 0; i < Sigma_size; i++)
{
int v = ch[u][i]; if (!v)continue;
dfs(v);
val[u] += val[v];
}
}
int find_kth(int u, int k) {
if (u)putchar(he[u]);
if (k <= Have_word[u])return u;
k -= Have_word[u];
for (int i = 0; i < Sigma_size; i++)
{
int v = ch[u][i]; if (!v)continue;
if (k <= val[v])
{
return find_kth(v, k);
}
else k -= val[v];
}
}
} ac;
int n, k;
char s[N];
int main() {
scanf("%s", s);
rd(k);
n = strlen(s);
for (int i = 0; i < n; i++)
{
for (int l = i, r = i; l >= 0 && r < n; l --, r ++)
{
if (s[l] == s[r])
if (l + 2 >= r - 2 || r - 2 < 0 || l + 2 >= n || good[l + 2][r - 2])
good[l][r] = true;
}
for (int l = i, r = i + 1; l >= 0 && r < n; l --, r ++)
{
if (s[l] == s[r])
if (l + 2 >= r - 2 || r - 2 < 0 || l + 2 >= n || good[l + 2][r - 2])
good[l][r] = true;
}
} ac.init();
for (int i = 0; i < n; i++)
{
int j = n - 1;
while (good[i][j] == false)j--;
char c = s[j + 1]; s[j + 1] = 0;
ac.insert(s + i, i);
s[j + 1] = c;
} ac.dfs(0);
ac.val[0] = 0;
ac.find_kth(0, k);
return 0;
}

ti
tri
Trie

Codeforces 577E Ann and Half-Palindrome 字典树的更多相关文章

  1. Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)

    E. Ann and Half-Palindrome time limit per test 1.5 seconds memory limit per test 512 megabytes input ...

  2. Codeforces 455B A Lot of Games(字典树+博弈)

    题目连接: Codeforces 455B A Lot of Games 题目大意:给定n.表示字符串集合. 给定k,表示进行了k次游戏,然后是n个字符串.每局開始.字符串为空串,然后两人轮流在末尾追 ...

  3. Educational Codeforces Round 12 E. Beautiful Subarrays 字典树

    E. Beautiful Subarrays 题目连接: http://www.codeforces.com/contest/665/problem/E Description One day, ZS ...

  4. 【codeforces 514C】Watto and Mechanism(字典树做法)

    [题目链接]:http://codeforces.com/contest/514/problem/C [题意] 给你n个字符串; 然后给你m个询问;->m个字符串 对于每一个询问字符串 你需要在 ...

  5. codeforces 1285D. Dr. Evil Underscores(字典树)

    链接:https://codeforces.com/problemset/problem/1285/D 题意:给n个数a1,a2,a3.....an,找到一个数X,使得X 异或所有的ai ,得到的ma ...

  6. Codeforces 633 C Spy Syndrome 2 字典树

    题意:还是比较好理解 分析:把每个单词反转,建字典树,然后暴力匹配加密串 注:然后我就是特别不理解,上面那种能过,而且时间很短,但是我想反之亦然啊 我一开始写的是,把加密串进行反转,然后单词正着建字典 ...

  7. Codeforces 948D Perfect Security 【01字典树】

    <题目链接> 题目大意: 给定两个长度为n的序列,可以改变第二个序列中数的顺序,使得两个序列相同位置的数异或之后得到的新序列的字典序最小. 解题分析: 用01字典树来解决异或最值问题.因为 ...

  8. Codeforces 514C Watto and Mechanism(字典树)

    题目链接  Watto and Mechanism 题意  给出$n$个串(相当于字典),然后给出$m$个询问. 每个询问以字符串的形式给出,你需要改变这个字符串中的任意一个字符 (必须改变且只能改变 ...

  9. Codeforces 706 D. Vasiliy's Multiset (字典树贪心)

    题目链接:http://codeforces.com/contest/706/problem/D 题意很简单不多说. 把一个数当作二进制插入字典树中,按照xor的性质,1找0,0找1,贪心即可. 注意 ...

随机推荐

  1. poj3411 Paid Roads

    思路: 搜索.注意点和边都有可能经过多次. 实现: #include <iostream> #include <cstdio> #include <vector> ...

  2. Unity笔记(3)自学第二天

    学习记录: 界面使用: 脚本使用: 脚本注意点:

  3. 关于FLASK WEB开发8d 数据库迁移的问题

    首先, 第一步,要删除data-dev.sqlite这个数据库 第二步,进行下面的重建 暂时的解决办法是: python manage.py shell In [2]: from app import ...

  4. TortoiseSVN客户端不能记住用户名和密码

    TortoiseSVN客户端重新设置用户名和密码 在第一次使用TortoiseSVN从服务器CheckOut的时候,会要求输入用户名和密码,这时输入框下面有个选项是保存认证信息,如果选了这个选项,那么 ...

  5. Dreamweaver启动出错--Designer.xml错误

    Designer.xml错误导致Dreamweaver CS4无法启动 xml parsing fatal error:Invalid document structure,line:1, file: ...

  6. Linux基础之操作系统

    一.什么是操作系统 简单来说,操作系统就是一个协调.管理和控制计算机硬件资源和软件资源的控制程序. 二.操作系统存在的意义 究根结底,我们日常对计算机的管理是对计算机硬件的管理.经过近百年的时间,现代 ...

  7. MERGE INTO USING用法

    MERGE INTO [your table-name] [rename your table here] USING ( [write your query here] )[rename your ...

  8. RocketMQ学习笔记(15)----RocketMQ的消息模式

    在前面学习ActiveMQ时,看到ActiveMQ可以是队列消息模式,也可以是订阅发布模式. 同样,在RocketMQ中,也存在两种消息模式,即是集群消费模式和广播消费模式. 1. 集群消费模式 跟A ...

  9. 简单工厂模式&工厂方法模式&抽象工厂模式的区别

    之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个 ...

  10. CAD使用DeleteXData删除数据(网页版)

    主要用到函数说明: MxDrawEntity::DeleteXData 删除扩展数据,详细说明如下: 参数 说明 pzsAppName 删除的扩展数据名称,如果为空,删除所有扩展数据 js代码实现如下 ...