ac自动机MLE情况下

来源:互联网 发布:多益网络面试测试 编辑:程序博客网 时间:2024/05/22 03:29

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5880

开结构体,不大好,因为很容易爆空间

额 下面的代码 用的时候就new出来,用完就delete,但还是MLE

[cpp] view plain copy
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<queue>  
  5. #include<algorithm>  
  6. #include<cctype>  
  7. using namespace std;  
  8. const int maxn=1000000+5;  
  9. const int letters=26;   
  10. struct CNode{  
  11.     CNode *pChilds[letters];  
  12.     CNode *pPrev;  
  13.     bool bBadNode,end; int len;   
  14.     CNode(){  
  15.         for(int i=0;i<letters;i++) pChilds[i]=NULL;  
  16.         bBadNode=end=false; len=0;  
  17.         pPrev=NULL;  
  18.     }  
  19. };  
  20. char str[maxn];  
  21. CNode* Q[maxn];  
  22. int head,tail;  
  23. void BuildDfa(CNode* root0,CNode* root1)  
  24. {  
  25.     for(int i=0;i<letters;i++)  
  26.         root0->pChilds[i]=root1;  
  27.     root1->pPrev=root0;  
  28.     root0->pPrev=NULL;  
  29.     head=tail=0;  
  30.     Q[head++]=root1;  
  31.     while(head!=tail)  
  32.     {  
  33.         CNode *root=Q[tail++];  
  34.         for(int i=0;i<letters;i++)  
  35.         {  
  36.             CNode *p=root->pChilds[i];  
  37.             if(p==NULL) continue;  
  38.             CNode *pPrev=root->pPrev;  
  39.             while(pPrev){  
  40.                 if(pPrev->pChilds[i]!=NULL){  
  41.                     p->pPrev=pPrev->pChilds[i];  
  42.                     if(p->pPrev->bBadNode)  
  43.                         p->bBadNode=true;  
  44.                     break;    
  45.                 }  
  46.                 else pPrev=pPrev->pPrev;  
  47.                }  
  48.             Q[head++]=p;  
  49.         }  
  50.     }      
  51. }  
  52. bool SearchDfa(CNode* root,char *s)  
  53. {  
  54.     CNode *p=root;  
  55.     for(int i=0;s[i];i++){  
  56.         if(!isalpha(s[i])) continue;  
  57.         for(;;){  
  58.             if(p->pChilds[tolower(s[i])-'a']!=NULL){  
  59.                 p=p->pChilds[tolower(s[i])-'a'];  
  60.                 CNode* pPrev=p;  
  61.                 while(pPrev->bBadNode){  
  62.                     if(pPrev->end){  
  63.                         for(int j=0;j<p->len;j++)  
  64.                             s[i-j]='*';  
  65.                         break;  
  66.                     }  
  67.                     pPrev=pPrev->pPrev;  
  68.                 }   
  69.                 break;  
  70.             }  
  71.             else p=p->pPrev;  //到前驱节点   
  72.         }  
  73.     }  
  74.     return false;  
  75. }  
  76. void Insert(CNode *root,char *s)  
  77. {  
  78.     for(int i=0;s[i];i++)  
  79.     {  
  80.         if(root->pChilds[s[i]-'a']==NULL)  
  81.             root->pChilds[s[i]-'a']=new CNode;  
  82.         root=root->pChilds[s[i]-'a'];  
  83.     }  
  84.     root->bBadNode=true;  
  85.     root->end=true;  
  86.     root->len=strlen(s);  
  87. }  
  88. void Dele(CNode* root){  
  89.     for(int i=0;i<letters;i++)  
  90.     if(root->pChilds[i]!=NULL)  
  91.         Dele(root->pChilds[i]);  
  92.     delete root;  
  93. }  
  94. int main()  
  95. {  
  96.     int T,n; cin>>T;  
  97.     while(T--)  
  98.     {  
  99.         CNode *root0=new CNode,*root1=new CNode;  
  100.         cin>>n;  
  101.         while(n--){  
  102.             scanf("%s",str);  
  103.             Insert(root1,str);  
  104.         }  
  105.         BuildDfa(root0,root1);  
  106.         getchar();  
  107.         gets(str);  
  108.         SearchDfa(root1,str);  
  109.         cout<<str<<endl;  
  110.         Dele(root1);  
  111.         delete root0;  
  112.     }  
  113.     return 0;  
  114. }  




所以还是数组好

试了一下,如果数组没用到,不会计入memory,但是结构体一旦new出来,就要全部算空间

并且什么都不干,单单开个1000000的数组,只要memset就会MLE

以下这句话摘自:博客

Q神说不要用memset一次性清空数组,超内存是我一次性memset数组导致的,将没有用的空间也用上了,于是试了下不一次性memset数组,果断不超了。


[cpp] view plain copy
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<queue>  
  5. #include<algorithm>  
  6. #include<cctype>  
  7. using namespace std;  
  8. const int INF=0x3f3f3f3f;  
  9. const int maxn=1000000+5;  
  10. const int letters=26;  
  11. const int pPrev=26;  
  12. const int len=27;  
  13. const int bBadNode=28;  
  14. const int End=29;  
  15. int nNode;  
  16. int tree[maxn][30];  
  17. char str[maxn];  
  18. int NewNode()   //用一个就开一个空间   
  19. {  
  20.     for(int i=0;i<30;i++) tree[nNode][i]=-1;  
  21.     nNode++;  
  22.     return nNode-1;  
  23. }  
  24. void init()  
  25. {  
  26.     nNode=2;  
  27.     for(int i=0;i<30;i++) tree[0][i]=tree[1][i]=-1;  
  28. }  
  29. void Insert(int root,char *s)  
  30. {  
  31.     for(int i=0;s[i];i++){  
  32.         if(tree[root][s[i]-'a']==-1)  
  33.             tree[root][s[i]-'a']=NewNode();  
  34.         root=tree[root][s[i]-'a'];  
  35.     }  
  36.     tree[root][len]=strlen(s);  
  37.     tree[root][bBadNode]=1;  
  38.     tree[root][End]=1;  
  39. }  
  40. void BuildDfa()  
  41. {  
  42.     for(int i=0;i<letters;i++)  
  43.         tree[0][i]=1;  
  44.     tree[1][pPrev]=0;  
  45.     tree[0][pPrev]=-1;  
  46.     queue<int> Q;  
  47.     Q.push(1);  
  48.     while(!Q.empty())  
  49.     {  
  50.         int root=Q.front(); Q.pop();  
  51.         for(int i=0;i<letters;i++)  
  52.         {  
  53.             int p=tree[root][i];  
  54.             if(p==-1) continue;  
  55.             int pp=tree[root][pPrev];  
  56.             while(pp!=-1)  
  57.                 if(tree[pp][i]!=-1){  
  58.                     tree[p][pPrev]=tree[pp][i];  
  59.                     if(tree[tree[p][pPrev]][bBadNode]==1)  
  60.                         tree[p][bBadNode]=1;  
  61.                     break;  
  62.                 }  
  63.                 else pp=tree[pp][pPrev];  
  64.             Q.push(p);  
  65.         }  
  66.     }  
  67. }  
  68. void SearchDfa(char *s)  
  69. {  
  70.     int p=1;  
  71.     for(int i=0;s[i];i++)  
  72.     {  
  73.         if(!isalpha(s[i])) {  
  74.             p=1; continue;  
  75.         }  
  76.         for(;;){  
  77.             if(tree[p][tolower(s[i])-'a']!=-1){  
  78.                 p=tree[p][tolower(s[i])-'a'];  
  79.                 int pp=p;  
  80.                 while(tree[pp][bBadNode]==1){  
  81.                     if(tree[pp][End]==1){  
  82.                         for(int j=0;j<tree[pp][len];j++)  
  83.                             s[i-j]='*';  
  84.                         break;  
  85.                     }  
  86.                     else pp=tree[pp][pPrev];  
  87.                 }  
  88.                 break;      
  89.             }  
  90.             else p=tree[p][pPrev];  
  91.         }  
  92.     }  
  93. }  
  94. int main()  
  95. {  
  96.     int T,n; scanf("%d",&T);  
  97.     while(T--)  
  98.     {  
  99.         scanf("%d",&n); nNode=2;  
  100.         init();  
  101.         while(n--){  
  102.             scanf("%s",str);  
  103.             Insert(1,str);  
  104.         }  
  105.         BuildDfa();  
  106.         getchar();  
  107.         gets(str);  
  108.         SearchDfa(str);  
  109.         cout<<str<<endl;  
  110.     }  
  111.     return 0;  
  112. }  
原创粉丝点击