NEUOJ 720 头哥的烦恼
来源:互联网 发布:搬瓦工vps搭建ss优化 编辑:程序博客网 时间:2024/06/05 06:41
题目意思:头哥,众所周知,作为acm队的主力选手,最近遇到了一些烦恼,那就是CET-4临近了,但是他还有很多单词没记住.
现在头哥有n个单词没记住,(所有的单词长度加起来不超过5e5),他需要区分其中的m对单词,因为两个单词前面有一部分是一样的,所以他只需要记住后面不相等的部分,所以头哥想要知道每对单词最长相等的前缀长度。
题目连接:
http://202.118.31.226/problem/720
思路就是,建个字典树在,所为的最长公共前缀,可以这样求,即是,两个字符串的最近公共祖先LCA 的那个字母的深度。
需要注意一下的是。我在自己的电脑上 结构体里开了个26*100000的数组,就运行错误了,交到oj 能AC ;
#include<stdio.h>#include<algorithm>#include<string>#include<string.h>using namespace std;const int maxnode=5*100000;int f[maxnode];int V=-1;struct Trie{ int ch[maxnode][26]; int val[maxnode]; int sz; Trie() { sz=1; memset(ch[0],0,sizeof(ch[0]));} int idx(char c) {return c-'a';} void insert(char *s,int v,int num) { int u=0, n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u][c]) { memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]=v; f[num]=u; V=max(V,u); }};char ss[100000*5+10];int parent[32][100000*5+10];int depth[100000*5+10];void dfs(int v,int p,int d,Trie &t1){ parent[0][v]=p; depth[v]=d; for(int i=0;i<26;i++) { if(t1.ch[v][i]!=0) { dfs(t1.ch[v][i],v,d+1,t1); } }}void init(int V){ for(int k=0;k+1<32;k++) { for(int v=0;v<=V;v++) { if(parent[k][v]<0) { parent[k+1][v]=-1; }else { parent[k+1][v]=parent[k][parent[k][v]]; } } }} int lca(int u,int v) { // printf("look %d %d %d %d\n",u,v,depth[u],depth[v]); if(depth[u]>depth[v]) swap(u,v); for(int k=0;k<32;k++) { if((depth[v]-depth[u])>>k&1){ // printf("depv%d depu%d %d %d\n",v,u,depth[v]-depth[u],parent[k][v]); v=parent[k][v]; } } if(u==v) return u; for(int k=32-1;k>=0;k--) { if(parent[k][u]!=parent[k][v]) { u=parent[k][u]; v=parent[k][v]; } } return parent[0][u]; } int main(){ //freopen("F:\\123.txt","r",stdin); int t,m,n; scanf("%d",&t); V=-1; for(int ik=1;ik<=t;ik++) { printf("Case #%d:\n",ik); //memset(parent,0,sizeof(parent)); //memset(depth,0,sizeof(depth)); Trie t1; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%s",ss); t1.insert(ss,1,i); } dfs(0,-1,0,t1); init(V); int u,v,pot; for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); pot=lca(f[u],f[v]); printf("%d\n",depth[pot]); } } return 0;}/* int query(char *s) { int u=0,n=strlen(s); for(int i=0;i<n;i++) { int c=idx(s[i]); if(!ch[u][c]) { return -1; }else { u=ch[u][c]; } } return 1&&val[u]; } */
0 0
- NEUOJ 720 头哥的烦恼
- NEUOJ: 1299: 磊磊的难题
- NEUOJ 720 (字典树+LCA || 二分+哈希)
- neuoj 1595
- neuoj 1632
- NEUOJ 1681
- NEUOJ Problem48
- 我的烦恼---来自studio2005的烦恼
- 成长的烦恼归来
- 《成长的烦恼》介绍
- 信息多的烦恼
- eclipse的烦恼!
- 最近的烦恼
- 翻译的烦恼
- 刷新DBGrid的烦恼
- 了却最后的烦恼
- 成长后的烦恼
- Compuware Softice的烦恼
- 构建高并发高可用的电商平台架构大纲
- 排序算法总结(4)——归并排序
- AliRedis单机180w QPS, 8台服务器构建1000w QPS Cache集群
- Android include标签的监听事件处理
- 快速排序算法
- NEUOJ 720 头哥的烦恼
- 主元素问题
- 原码、反码、补码知识详细讲解(此作者是我找到的讲的最细最明白的一个)
- java设计模式(十一)--状态模式
- C002-CPP-用malloc()存储任意长度的键入字符串
- Microsoft资源
- 阿里云ECS云主机的选择
- SVN-之Clean up失败
- 【leetCode】Binary Tree Zigzag Level Order Traversal python实现