Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)
来源:互联网 发布:今日头条 java 编辑:程序博客网 时间:2024/05/01 11:24
http://codeforces.com/contest/557/problem/E
大致题意:找出s的子串中字典序第k小的“半回文串”,给出半回文串定义是:对于任意i<=|s|/2 有s[i] = s[len-i+1]
数据量是5000
O(n^2)的算法可行
简单暴力的方法就是n^2 dp 出(i,j)的子串是不是半回文串,再把所有子串插入字典树,在dfs遍历出第k小的串
方法二,dp[i][j]统计出以i为始端到i~j的子串是回文串的总数,再把所有子串插入字典树,然后二分出答案子串。
方法一:
#include <iostream>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <sstream>#include <string>#include <vector>#include <cstdio>#include <ctime>#include <bitset>#include <algorithm>#define SZ(x) ((int)(x).size())#define ALL(v) (v).begin(), (v).end()#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)#define REP(i,n) for ( int i=1; i<=int(n); i++ )using namespace std;typedef long long ll;const int N = 5000+5;int dp[N][N];char s[N];int k;int n;struct node{ node *son[2]; int cnt; node() { memset(son,0,sizeof(son)); cnt = 0; }}trie[N*N];int SZ = 0;node *root,*cur;node *createnode(){ return &trie[SZ++];}void Insert(int p){ cur = root; for(int i = p;i <= n;i++) { int val = s[i]-'a'; if(cur->son[val] == NULL) cur->son[val] = createnode(); cur = cur->son[val]; cur->cnt += dp[p][i]; }}int getsum(node *cur){ int sum = 0; if(cur->son[0]) sum += getsum(cur->son[0]); if(cur->son[1]) sum += getsum(cur->son[1]); cur->cnt += sum; return cur->cnt;}vector<char>ans;bool dfs(node *cur,int &k){ if( k <= 0) return true; if(cur->son[0]) { ans.push_back('a'); if(cur->son[0]->cnt) k -= cur->son[0]->cnt; if(dfs(cur->son[0],k)) return true; ans.pop_back(); } if(cur->son[1]) { ans.push_back('b'); if(cur->son[1]->cnt)k -= cur->son[1]->cnt; if(dfs(cur->son[1],k)) return true; ans.pop_back(); } return false;}int main(){ scanf("%s%d",s+1,&k); n = strlen(s+1); for(int i =0;i <= n+2;i++) for(int j = i;j >= 0;j--) dp[i][j] = 1; for(int len = 2;len <= n;len++) for(int l = 1;l+len-1 <= n;l++) { int r = l+len-1; dp[l][r] = (s[l] == s[r] && dp[l+2][r-2]); } root = createnode(); REP(i,n)Insert(i); dfs(root,k); foreach(i,ans) putchar(*i);}
方法二:
//GNU C++Accepted374 ms392200 KB#include <iostream>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <sstream>#include <string>#include <vector>#include <cstdio>#include <ctime>#include <bitset>#include <algorithm>#define SZ(x) ((int)(x).size())#define ALL(v) (v).begin(), (v).end()#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)#define REP(i,n) for ( int i=1; i<=int(n); i++ )using namespace std;typedef long long ll;const int N = 5000+5;int dp[N][N];char s[N];int k;int n;struct node{ node *son[2]; int cnt; node() { memset(son,0,sizeof(son)); cnt = 0; }}trie[N*N];int SZ = 0;node *root,*cur;node *createnode(){ return &trie[SZ++];}void Insert(int p){ cur = root; for(int i = p;i <= n;i++) { int val = s[i]-'a'; if(cur->son[val] == NULL) cur->son[val] = createnode(); cur = cur->son[val]; if(i != p)cur->cnt += dp[p][n]-dp[p][i-1]; else cur->cnt += dp[p][n]; }}void query(node*cur,int k) //二分过程{ if(k <= 0) return ; if(cur->son[0] && cur->son[0]->cnt >= k) { int cnt = cur->son[0]->cnt; cur = cur->son[0]; if(cur->son[0]) cnt -= cur->son[0]->cnt; if(cur->son[1]) cnt -= cur->son[1]->cnt; putchar('a'); query(cur,k-cnt); } else if(cur->son[1]) { if(cur->son[0]) k -= cur->son[0]->cnt; int cnt = cur->son[1]->cnt; cur = cur->son[1]; if(cur->son[0]) cnt -= cur->son[0]->cnt; if(cur->son[1]) cnt -= cur->son[1]->cnt; putchar('b'); query(cur,k-cnt); }}int main(){ scanf("%s%d",s+1,&k); n = strlen(s+1); for(int i =0;i <= n+2;i++) for(int j = i;j >= 0;j--) dp[i][j] = 1; for(int len = 2;len <= n;len++) for(int l = 1;l+len-1 <= n;l++) { int r = l+len-1; dp[l][r] = (s[l] == s[r] && dp[l+2][r-2]); } REP(i,n) for(int j = i+1;j <= n;j++) dp[i][j] += dp[i][j-1]; root = createnode(); REP(i,n) Insert(i); query(root,k);}
0 0
- Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)
- Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome (DP+字典树)
- Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome 字典树
- Codeforces 557E Ann and Half-Palindrome DP+字典树
- cf #311 E. Ann and Half-Palindrome (dp+字典树)
- Codeforces 311(div 2):E. Ann and Half-Palindrome
- Codeforces 557E - Ann and Half-Palindrome (字典树+DP)
- Codeforces 577E Ann and Half-Palindrome 字典树
- [字典树] Codeforces 557E Ann and Half-Palindrome
- [字典树] Codeforces 557E Ann and Half-Palindrome
- codeforces #311 557E E. Ann and Half-Palindrome(trie+dp+dfs)
- codeforces 557 E Ann and Half-Palindrome
- Codeforces 557E Ann and Half-Palindrome (字典树+字符串排序)
- Codeforces 557E Ann and Half-Palindrome (Trie树)
- [Codeforces 557E] Ann and Half-Palindrome (Trie树+子串排序)
- 找出s的子串中字典序第k小的“半回文串” Trie Codeforce Div. 2 Ann and Half-Palindrome
- Codeforces Round #353 (Div. 2) E. Trains and Statistic (线段树+dp)
- Codeforces Round #261 (Div. 2) E. Pashmak and Graph【DP】
- Romantic(扩展欧几里得算法)
- linux中tomcat部署项目报错,如何显示错误信息?
- Serializable:writeObject/readObject有的限制?
- 用Material Design设计App谷歌官方文档翻译
- 电脑硬件知识扫盲 菜鸟提升必看电脑配置知识
- Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)
- JSP跳转中request共享问题
- 排序
- SSH分页(Hibernate实现简单分页查询)
- 人机交互未来:技术先靠边站!
- reason: '* -[NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
- POJ 2105 IP Address(水~)
- STM32F405 DFU更新固件
- hdu 1010 Tempter of the Bone