Advertisement
Guest User

Harder, Better, Faster, Smaller

a guest
Jul 28th, 2012
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.03 KB | None | 0 0
  1. // Have a great day, hope you're enjoying the Olympics as much as I am :)
  2.        
  3. #include <cstdio>
  4. #include <map>
  5. using namespace std;
  6. typedef unsigned su;
  7. static unsigned char buf[1400000];
  8. static unsigned const UP=256;
  9. map<unsigned,su> good;
  10.  
  11. su fail[105000];
  12. su back[105000];
  13. su at=1;
  14.  
  15. int main(){
  16.   unsigned char* p=buf;
  17.   good[1<<30]=0;
  18.   int res=1<<30;
  19.  
  20.   { // read the input
  21.     fread(buf,(sizeof buf)-1,1,stdin);
  22.   }
  23.  
  24.   { // insert words
  25.     su words=0;
  26.     while (*p>='0' and *p<='9') words=words*10+(p++[0]&0x0F);
  27.     while (*p!='\n') ++p;
  28.     while (words-->0){
  29.       su on=0, len=0;
  30.       for (unsigned c; (c=0xFFu&*++p)!='\n';){
  31.         if (not good.count(on*UP+c)) good[on*UP+c]=(at++);
  32.         on=good[on*UP+c];
  33.         ++len;
  34.       }
  35.       back[on]=len;
  36.     }
  37.   }
  38.  
  39.   { // build the automaton
  40.     su todo[115000]; todo[0]=0;
  41.     for (unsigned i=0,j=0; i<=j; ++i){
  42.       su on=todo[i];
  43.       for (map<unsigned,su>::const_iterator it=good.lower_bound(todo[i]*UP); it->first<(todo[i]+1)*UP; ++it){
  44.         unsigned const tr=(it->first&0xFFu);
  45.         su to=todo[++j]=it->second;
  46.         fail[to]=fail[on];
  47.         while (fail[to] and not good.count(fail[to]*UP+tr)) fail[to]=fail[fail[to]];
  48.         if (fail[to]!=on and good.count(fail[to]*UP+tr)){
  49.           fail[to]=good[fail[to]*UP+tr];
  50.           back[to]=max(back[to],back[fail[to]]);
  51.         }
  52.       }
  53.     }
  54.   }
  55.  
  56.   { // run the search
  57.     su lines=0;
  58.     for (++p; *p>='0' and *p<='9';) lines=lines*10+(p++[0]&0x0F);
  59.  
  60.     unsigned char* off=p;
  61.     su line=1;
  62.     su on=0;
  63.  
  64.     while (line<=lines){
  65.       if (*++p=='\n'){
  66.         if (res!=(1<<30)){
  67.           printf("%d %d\n",line,res);
  68.           return 0;
  69.         }
  70.         ++line;
  71.         off=p;
  72.         on=0;
  73.       }else{
  74.         while (on and !good.count(on*UP+(unsigned)*p)) on=fail[on];
  75.         if (good.count(on*UP+(unsigned)*p)) on=good[on*UP+(unsigned)*p];
  76.         if (back[on]){
  77.           res=min(res,(int)(p-off-back[on]+1));
  78.         }
  79.       }
  80.     }
  81.   }
  82.  
  83.   puts("Passed");
  84. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement