小测试题解

 

一开始就想到一个暴力的做法(虽然也知道正解应该是后缀自动机)

把每一个字符串的每一个前缀都倒着加入字典树

然后就变成了经典的树博弈(根节点不能取,因为根是空的)

sg函数为,子树sg的xor和加权值(除根节点外权值都为1,因为每一个节点都只代表一个字符串)

但是这样是n方的,不过不会后缀自动机所以只好暴力

用后缀自动机的话就是建parent树,然后做带权值的树博弈(其实和普通的树博弈差不多,普通的只是权值都为1而已,权值为这个节点代表的字符串个数)

 

  1 {$M 50000000}
  2 const
  3     maxn=2000010;
  4 type
  5     node=record
  6       go:array['0'..'9']of longint;
  7       step,fa:longint;
  8     end;
  9 
 10 var
 11     sam:array[0..maxn]of node;
 12     first,stop,next,min:array[0..maxn]of longint;
 13     s,ans:ansistring;
 14     tot,last,t,num:longint;
 15 
 16 procedure add(x:char);
 17 var
 18     now,new,q:longint;
 19 begin
 20     inc(tot);
 21     now:=tot;
 22     fillchar(sam[now].go,sizeof(sam[now].go),0);
 23     sam[now].step:=sam[last].step+1;
 24     while (last<>0)and(sam[last].go[x]=0) do
 25       begin
 26         sam[last].go[x]:=now;
 27         last:=sam[last].fa;
 28       end;
 29     if last=0 then sam[now].fa:=1
 30     else
 31       begin
 32         q:=sam[last].go[x];
 33         if sam[q].step=sam[last].step+1 then sam[now].fa:=q
 34         else
 35           begin
 36             inc(tot);
 37             new:=tot;
 38             sam[new]:=sam[q];
 39             sam[q].fa:=new;
 40             sam[now].fa:=new;
 41             sam[new].step:=sam[last].step+1;
 42             while (last<>0)and(sam[last].go[x]=q) do
 43               begin
 44                 sam[last].go[x]:=new;
 45                 last:=sam[last].fa;
 46               end;
 47           end;
 48       end;
 49     last:=now;
 50 end;
 51 
 52 procedure insert(x,y:longint);
 53 begin
 54     inc(num);
 55     stop[num]:=y;
 56     next[num]:=first[x];
 57     first[x]:=num;
 58     min[y]:=sam[x].step+1;
 59 end;
 60 
 61 function dfs(x:longint):longint;
 62 var
 63     i:longint;
 64 begin
 65     dfs:=0;
 66     i:=first[x];
 67     while i<>0 do
 68       begin
 69         dfs:=dfs xor dfs(stop[i]);
 70         i:=next[i];
 71       end;
 72     inc(dfs,sam[x].step-min[x]+1);
 73 end;
 74 
 75 procedure main;
 76 var
 77     i:longint;
 78 begin
 79     readln(s);
 80     for i:=1 to tot do
 81       first[i]:=0;
 82     last:=1;
 83     tot:=1;
 84     fillchar(sam[1].go,sizeof(sam[1].go),0);
 85     for i:=1 to length(s) do
 86       add(s[i]);
 87     for i:=2 to tot do
 88       insert(sam[i].fa,i);
 89     if dfs(1)=1 then writeln('codechef')
 90     else writeln('topcoder');
 91 end;
 92 
 93 begin
 94 assign(input,'game.in');
 95 reset(input);
 96 assign(output,'game.out');
 97 rewrite(output);
 98     readln(t);
 99     while t<>0 do
100       begin
101         main;
102         dec(t);
103       end;
104 close(input);
105 close(output);
106 end.
View Code

相关文章: