摘要: 重复至少俩次的不重叠子串的个数我还是觉得大牛的这句解释十分重要,还是没彻底理解透,导致今天这道题目的悲剧若在假设重复子串的长度最多为L的限制下有解, 则对于任意一个比L小的限制L'<L, 也一定有解. 这就说明存在解的连续性给出一个关于LCP的定理LCP(SA[i], SA[j]) = RMQ(Height[i+1..j]). 由此, 若存在k, 满足Height[k] < L, 则对于所有i, j 满足i < k < j, 有LCP(SA[i], SA[j]) < L. 即公共长度至少为L的两个后缀, 不会跨过一个小于L的Height低谷k, 所以我们可 阅读全文
posted @ 2011-05-19 21:24 枕边梦 阅读(422) 评论(0) 推荐(0)
摘要: 啊,好 郁闷,这应该就是不理解模板的带来的后果吧,用之前那个模板,写了好几遍,改了好几遍,一直wa,可是换一个模板就过了,之后还是用这个模板吧题意倒是很简单,就是求出至少重复k次的最长子串还是用二分的思想,找出一组后缀数目大于等于k的最大后缀即可#include <stdio.h> #include <stdlib.h> #include <string.h> int const N= 20100; int wa[N], wb[N], ws[N*2], wv[N]; int rank[N], sa[N], height[N], r[N], n, k,m; i 阅读全文
posted @ 2011-05-18 22:16 枕边梦 阅读(226) 评论(0) 推荐(0)
摘要: 这个地址上的题解已经好详细了http://wenku.baidu.com/view/87f5b7f80242a8956bece4df.html不过本人觉得,加上这部分题解的话,会更好理解若在假设重复子串的长度最多为L的限制下有解, 则对于任意一个比L小的限制L'<L, 也一定有解. 这就说明存在解的连续性, 这样就可以用二分查找答案长度L. 给出一个关于LCP的定理LCP(SA[i], SA[j]) = RMQ(Height[i+1..j]). 由此, 若存在k, 满足Height[k] < L, 则对于所有i, j 满足i < k < j, 有LCP(SA[i 阅读全文
posted @ 2011-05-17 22:57 枕边梦 阅读(431) 评论(0) 推荐(0)
摘要: 嘿嘿,用大牛的代码过的,我觉得,要理解这个好难呀,但要是用了模板计算后缀数组sa[],名次数组rank[],还有height[],height[]是后缀数组的关键所在,用来模板计算出这三个数组,后缀数组的应用也就拓展得开了哦看下模板吧,不过这个版本用了657ms耶,不是很快的说#include <iostream>using namespace std;#define MAXN 200010// max{str.len,256}int b[MAXN],array[4][MAXN],*rank1,*nrank,*sa,*nsa,height[MAXN],n,len;char str[ 阅读全文
posted @ 2011-05-17 20:45 枕边梦 阅读(232) 评论(0) 推荐(0)
摘要: 擅长排列的小明时间限制:1000 ms | 内存限制:65535 KB 难度:4描述 小明十分聪明,而且十分擅长排列计算。比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想为难他,在这5个数字中选出几个数字让他继续全排列,那么你就错了,他同样的很擅长。现在需要你写一个程序来验证擅长排列的小明到底对不对。输入 第一行输入整数N(1<N<10)表示多少组测试数据,每组测试数据第一行两个整数 n m (1<n<9,0<m<=n) 输出 在1-n中选取m个字符进行全排列,按字典序全部输出,每种排列占一行,每组数据间不需分界。如样例 样例输入 23 1 阅读全文
posted @ 2011-05-17 10:22 枕边梦 阅读(1618) 评论(0) 推荐(0)
摘要: 这题目郁闷死了,因为一些小错误,搞了半天,不过,要注意的东西真的很多哦题意是找出单词的所有符号要求的匹配模式,首先将模式存入字典树中,再用单词进行查找需要注意的问题:看到输出的sample也应该知道了,一个单词有多种匹配模式,用一个单词进行遍历时,到达同一个单词的结尾,却可能经历了不同的匹配模式,所以这里用了并查集来保存具体的,还是结合代码吧,比较好解释#include<iostream>#include<string>#include<algorithm>using namespace std;struct node{ int num;//保存模式的编号 阅读全文
posted @ 2011-05-16 17:22 枕边梦 阅读(363) 评论(0) 推荐(0)
摘要: 额,这题,我好想看到分类说是用trie树,可是怎么想也没什么思路,就用了暴力了若找不到相同的单词,则相似的也只有三种情况代码很好理解#include<iostream>using namespace std;#define MAXN 10001char str[MAXN][20];bool replace(char *a,char *b){ int l1=strlen(a); int l2=strlen(b); if(l1==l2)//修改一个字符 { int i=0; while(i<l1&&a[i]==b[i])//找到第一个不同的字符的位置 i++; w 阅读全文
posted @ 2011-05-15 20:41 枕边梦 阅读(180) 评论(0) 推荐(0)
摘要: 唉,又这样贡献了一个WA,忘了把自己的用来测试的输出删了……一开始还真被这题目吓住了,不过花点心思想想,还是可以做出来的题意要求的是打印单词的最少操作数只有三个操作:输入,删除,还有打印,前缀就不需要重复输入,想到了字典树,这道题目也就好做了要 求最少的操作数,所以首先要归类,所有拥有相同前缀的单词,放在一块输入,题目还说,最后一次打印不需要删除理论上是像上面说的,但实际我们在计算最少操作数时,可以这样算,首先假设所有的单词都需要重新打印还有删除,所以总操作数是单词总长度*2接下来,计算出前缀,可以这样想,只需计算出每一个节点被哪些单词共有,如题目中的样例,“freeradiant”,“fre 阅读全文
posted @ 2011-05-15 18:07 枕边梦 阅读(1120) 评论(0) 推荐(0)
摘要: 额,比较简单的字典树,找出一个单词最短而且唯一的前缀,就是不会跟其他单词重复这样的话,插入只需在每一个单词经过的路径的节点p->v上累加,查找时,检查p->v的值,当p->==1时,即到此节点为止的前缀是最短而且是唯一的不知道大牛的0ms是怎么做出来的,,我用了16ms,膜拜啊#include<iostream>#include<string>using namespace std;struct node{ node *next[26]; int v;};node *root;char str[1001][21];void insert(char *s 阅读全文
posted @ 2011-05-15 14:55 枕边梦 阅读(187) 评论(0) 推荐(0)
摘要: 一道水题,居然改错改了一个多小时题目的意思是其实就是找出一个单词,前半部是一个出现过的单词,后半部也是,记住,要严格满足这个条件所以,其实也就是先查找一个单词的是否有前缀,再用这个单词除去前缀的部分查找是否存在一个这样的单词虽然题目说按字典序输出,但本身已经是按字典序输入了,所以排序也就省了#include<iostream>#include<string>using namespace std;struct node{ int v; node *next[26];};node *root;char str[50002][50];void insert(char *s) 阅读全文
posted @ 2011-05-15 14:15 枕边梦 阅读(1512) 评论(1) 推荐(0)