Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Have a great day, hope you're enjoying the Olympics as much as I am :)
- #include <cstdio>
- #include <map>
- using namespace std;
- typedef unsigned su;
- static unsigned char buf[1400000];
- static unsigned const UP=256;
- map<unsigned,su> good;
- su fail[105000];
- su back[105000];
- su at=1;
- int main(){
- unsigned char* p=buf;
- good[1<<30]=0;
- int res=1<<30;
- { // read the input
- fread(buf,(sizeof buf)-1,1,stdin);
- }
- { // insert words
- su words=0;
- while (*p>='0' and *p<='9') words=words*10+(p++[0]&0x0F);
- while (*p!='\n') ++p;
- while (words-->0){
- su on=0, len=0;
- for (unsigned c; (c=0xFFu&*++p)!='\n';){
- if (not good.count(on*UP+c)) good[on*UP+c]=(at++);
- on=good[on*UP+c];
- ++len;
- }
- back[on]=len;
- }
- }
- { // build the automaton
- su todo[115000]; todo[0]=0;
- for (unsigned i=0,j=0; i<=j; ++i){
- su on=todo[i];
- for (map<unsigned,su>::const_iterator it=good.lower_bound(todo[i]*UP); it->first<(todo[i]+1)*UP; ++it){
- unsigned const tr=(it->first&0xFFu);
- su to=todo[++j]=it->second;
- fail[to]=fail[on];
- while (fail[to] and not good.count(fail[to]*UP+tr)) fail[to]=fail[fail[to]];
- if (fail[to]!=on and good.count(fail[to]*UP+tr)){
- fail[to]=good[fail[to]*UP+tr];
- back[to]=max(back[to],back[fail[to]]);
- }
- }
- }
- }
- { // run the search
- su lines=0;
- for (++p; *p>='0' and *p<='9';) lines=lines*10+(p++[0]&0x0F);
- unsigned char* off=p;
- su line=1;
- su on=0;
- while (line<=lines){
- if (*++p=='\n'){
- if (res!=(1<<30)){
- printf("%d %d\n",line,res);
- return 0;
- }
- ++line;
- off=p;
- on=0;
- }else{
- while (on and !good.count(on*UP+(unsigned)*p)) on=fail[on];
- if (good.count(on*UP+(unsigned)*p)) on=good[on*UP+(unsigned)*p];
- if (back[on]){
- res=min(res,(int)(p-off-back[on]+1));
- }
- }
- }
- }
- puts("Passed");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement