题目链接

题意:

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

给定一个字符串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. leetcode377 Combination Sum IV

    思路: dp. 实现: class Solution { public: int combinationSum4(vector<int>& nums, int target) { ...

  2. python--12、pymysql模块

    安装 pip3 install pymysql 使用方法(示例表为用户注册信息表): import pymysql user=input('username: ').strip() pwd=input ...

  3. Python之数据聚合与分组运算

    Python之数据聚合与分组运算 1. 关系型数据库方便对数据进行连接.过滤.转换和聚合. 2. Hadley Wickham创建了用于表示分组运算术语"split-apply-combin ...

  4. (转) 淘淘商城系列——Redis集群的搭建

    http://blog.csdn.net/yerenyuan_pku/article/details/72860432 本文我将带领大家如何搭建Redis集群.首先说一下,为何要搭建Redis集群.R ...

  5. 个人作业Alpha项目测试

    这个作业属于哪个课程 软件工程原理 这个作业要求在哪里 作业要求 团队名称 TEAMPANTHER 这个作业的目标 每个同学必须选取非自己所在团队的3个项目进行测试. 在你所测试的项目的Alpha发布 ...

  6. Git 分支使用

    一个主分支肯定是不够用的,不同的开发最好放在不同的分支上,在最后进行合并,不然在开发中会相互干扰. PS:环境Window xp,Git-1.8.4-preview20130916(http://gi ...

  7. php第二十六节课

    会话购物车 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...

  8. Python supprocess模块

    当我们需要调用系统的命令的时候,最先考虑的os模块.用os.system()和os.popen()来进行操作.但是这两个命令过于简单,不能完成一些复杂的操作,如给运行的命令提供输入或者读取命令的输出, ...

  9. linux下的进程

    一.进程的基础: 1.程序:程序是一些保存在磁盘上的指令的有序集合: 2.进程:进程是程序的一次执行过程: 3.进程与程序的关系:①.程序是静态的,进程是动态的:  ②.一个程序可以对应多个进程:   ...

  10. __repr__()

    class A : def __init__(self,name): self.name=name #def __str__(self): # return '**%s**'%self.name de ...