[Codeforces 557E] Ann and Half-Palindrome (Trie树+子串排序)
来源:互联网 发布:手机号码标记软件 编辑:程序博客网 时间:2024/05/01 14:12
Codeforces - 557E
给定一个只有a和b的字符串,输出它第 K 个半回文子串
半回文串的定义是,所有奇数位置都是回文的
其中字符串长度不超过5000 ,保证有解
可以直接暴力找出所有半回文串,复杂度
问题就在于如何找第 K大的,直接暴力排序是不支持的
我太久没做字符串题了,套路全忘光了
于是偷瞄了一下题解,看到了一个Trie这个单词
然后一下子就脑补出怎么做了 orzzzzzzzzzz
大概就是把所有的子串全部插入一个trie中
记录下每个子串的末尾在 trie中的位置,
这样一来每次只插入一个字符,复杂度就是
然后再暴力找半回文串,找到之后在trie上加一下权值
最后中序dfs这棵trie树,就能找到第 K大啦
#pragma comment(linker, "/STACK:102400000,102400000")#include <cstdio>#include <iostream>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <cctype>#include <map>#include <set>#include <queue>#include <bitset>#include <string>#include <complex>using namespace std;typedef pair<int,int> Pii;typedef long long LL;typedef unsigned long long ULL;typedef double DBL;typedef long double LDBL;#define MST(a,b) memset(a,b,sizeof(a))#define CLR(a) MST(a,0)#define SQR(a) ((a)*(a))#define PCUT puts("\n----------")const int maxl=5e3+3;struct Trie{ struct node { char chr; int val, nxt[2]; }; vector<node> T; int len,tot; char ans[maxl]; void init() { T.clear(); T.push_back({0,0,0,0}); tot=0; } int append(int,char); void update(int); int find(int,int=0,int=0);};char in[maxl];int N, K, tail[maxl][maxl];bool hp[maxl][maxl];Trie tree;int main(){ #ifdef LOCAL freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout); #endif while(~scanf(" %s%d", in, &K)) { CLR(tail); CLR(hp); tree.init(); N = strlen(in); for(int i=0; i<N; i++) { tail[i][i] = tree.append(0, in[i]); for(int j=i+1; j<N; j++) tail[i][j] = tree.append(tail[i][j-1], in[j]); } for(int l=1; l<=N; l++) for(int i=0,j=i+l-1; j<N; i++,j++) if(in[i]==in[j]) { int ii=i+2, jj=j-2; if(ii<=jj && !hp[ii][jj]) continue; hp[i][j] = 1; tree.update(tail[i][j]); } int len = tree.find(K); reverse(tree.ans, tree.ans+len); puts(tree.ans); } return 0;}int Trie::append(int pos, char chr){ chr -= 'a'; if(!T[pos].nxt[chr]) { T.push_back({char(chr+'a'),0,0,0}); T[pos].nxt[chr] = T.size()-1; } return T[pos].nxt[chr];}void Trie::update(int pos){ T[pos].val ++;}int Trie::find(int K, int pos, int d){ int nxp; tot += T[pos].val; if(tot>=K) { ans[0] = T[pos].chr; return len = d; } if(nxp = T[pos].nxt[0]) { if(find(K, nxp, d+1)) { ans[len-d] = T[pos].chr; return len; } } if(nxp = T[pos].nxt[1]) { if(find(K, nxp, d+1)) { ans[len-d] = T[pos].chr; return len; } } return 0;}
0 0
- [Codeforces 557E] Ann and Half-Palindrome (Trie树+子串排序)
- Codeforces 557E Ann and Half-Palindrome (Trie树)
- codeforces 557 E Ann and Half-Palindrome
- [字典树] Codeforces 557E Ann and Half-Palindrome
- Codeforces 557E Ann and Half-Palindrome DP+字典树
- [字典树] Codeforces 557E Ann and Half-Palindrome
- codeforces #311 557E E. Ann and Half-Palindrome(trie+dp+dfs)
- Codeforces 557E Ann and Half-Palindrome (字典树+字符串排序)
- Codeforces 557E - Ann and Half-Palindrome (字典树+DP)
- Codeforces 577E Ann and Half-Palindrome 字典树
- Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)
- Codeforces 311(div 2):E. Ann and Half-Palindrome
- Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome (DP+字典树)
- Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome 字典树
- cf #311 E. Ann and Half-Palindrome (dp+字典树)
- 找出s的子串中字典序第k小的“半回文串” Trie Codeforce Div. 2 Ann and Half-Palindrome
- [codeforces] 501E - Misha and Palindrome Degree
- Codeforces-665E-Beautiful Subarrays Trie树(字典树)
- scala语言规范
- 画板的实现
- spark hbase hbase-rdd
- 【cogs2593】幂,暴搜+容斥
- Android Permission权限控制机制
- [Codeforces 557E] Ann and Half-Palindrome (Trie树+子串排序)
- 树莓派基础网络设置
- RESTful API 返回结果设计
- 【NOIP2014模拟】逻辑的连通性 (Standard IO)
- 【模板】Trie树模板
- elasticsearch去重计数(distinct)
- 用内存映射文件来处理大文件
- 利用WindowManager生成悬浮按钮及悬浮菜单
- JAVA的基本数据类型