题目链接

题意:

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

给定一个字符串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. NodeJs学习记录(二)win7下 配置node连接oracle的环境

    2017/01/23 星期一 前言:还没看几眼教程,就开始分配任务,涉及到连oracle数据库,所以顺便把整个环境的配置放上来 安装文件清单(1).node-v6.9.1-x64.msi(2).pyt ...

  2. Linux 学习(二)

    Linux相关命令 命令 说明 startx 当前用户界面切换至图形界面 init5 切换至另一用户的图形化界面 init3 从图形界面切换回文本界面 pwd 显示当前用户路径 logout 注销 s ...

  3. 导入RPA应该了解的一些知识

    上次概要介绍了下RPA的基本知识,这次说一下导入RPA时应该知道的一些知识点. RPA是为了实现用软件自动化代替在各个行业中用人操作电脑办公的这部分业务,即使是在多个应用之间需要共享数据才能完成的业务 ...

  4. Java 基础入门随笔(3) JavaSE版——逻辑运算符、位运算符

    上一节写了一些运算符的注意事项,这节开头依然是对运算符的一些注意点的阐述! 比较运算符除了>.>=.<.<=.==.!=之外需要注意instanceof:检查是否是类的对象,例 ...

  5. jquery选择器,筛选器,属性,事件 基础

    左边栏实例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  6. CPU 的寻址方式

    来源https://baike.baidu.com/item/%E5%AF%BB%E5%9D%80%E6%96%B9%E5%BC%8F/3210621?fr=aladdin 寻址方式就是处理器根据指令 ...

  7. BZOJ5314: [Jsoi2018]潜入行动 (树形DP)

    题意:一棵树选择恰好k个结点放置监听器 每个监听器只能监听相邻的节点 问能使得所有节点被监听的种类数 题解:反正就是很well-known的树形DP了 至于时间复杂度为什么是nk 不会不学 很好想到四 ...

  8. vue-quill-editor + element-ui upload实现富文本图片上传

    代码贴上 <template> <div class="quill-editor-example"> <div class="box&quo ...

  9. Linux常用命令——压缩与解压缩命令

    常用压缩格式:  .zip   .gz   .bz2   .tar.gz   .tar.bz2 1..zip格式压缩 zip 压缩文件名 源文件 压缩文件 zip -r 压缩文件名 源目录 压缩目录 ...

  10. 洛谷——P1073 最优贸易

    P1073 最优贸易 n 个城市间以 m 条有向道路连接, 小 T 从 1 号城市出发, 将要去往 n 号城市.小 T 观察到一款商品 Z 在不同的城市的价格可能不尽相同,小 T 想要在旅行中的某一个 ...