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
原创粉丝点击