抄卡组
jzojAC无能,只能在bzoj上心灵AC
首先先把所有字符串哈希掉,然而$2*10^{8}$开不下数组,只能上vector
对于每组数据,我们分两种情况考虑
①所有字符串都有$*$
对于这种情况,我们只需要让所有字符串的前缀后缀相等就可以了,因为通配符一定会使各串匹配
至于如何比较,我们把所有字符串分别按前缀、后缀长度由短到长排序,然后相邻两个之间比较就可以了
②部分或全部字符串没有$*$
对于这种情况,首先需要所有没有通配符的字符串完全相等,这个就直接比较哈希值就行了
然后考虑有通配符和没有通配符的串(暂且把它们分别叫做匹配串和标准串好了)之间的匹配
首先还是前后缀必须相等,然后我们把匹配串中的所有被通配符隔开的字符串取出来,和标准串匹配即可
细节比较多,上代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define maxl 10000000 4 #define maxn 100000 5 #define BASE 2333 6 #define pb push_back 7 typedef unsigned long long ull; 8 int n,T; 9 ull bs[maxl+5]; 10 bool flag; 11 struct node{ 12 int cc,len; 13 vector<ull>hsh; 14 vector<int>ch; 15 bool operator<(const node &a)const{ 16 if(flag)return ch[1]<a.ch[1]; 17 else return len-ch[cc]<a.len-a.ch[a.cc]; 18 } 19 void clr(){ 20 cc=len=0; 21 hsh.clear(),hsh.pb(0); 22 ch.clear();ch.pb(0); 23 } 24 void gthsh(string t){ 25 for(int i=0;i<(int)t.length();i++){// 26 hsh.pb(hsh.back()*BASE+t[i]); 27 len++; 28 if(t[i]=='*')++cc,ch.pb(len); 29 } 30 } 31 ull gthsh(int l,int r){ 32 return hsh[r]-hsh[l-1]*bs[r-l+1]; 33 } 34 bool pipi(node &t){ 35 int sur=len-ch[cc]; 36 if(t.len<sur+ch[1]-1)return false; 37 if(gthsh(1,ch[1]-1)!=t.gthsh(1,ch[1]-1))return false; 38 if(gthsh(ch[cc]+1,len)!=t.gthsh(t.len-sur+1,t.len))return false; 39 int st=ch[1],end=t.len-sur; 40 for(int i=1;i<cc;i++){ 41 int length=ch[i+1]-ch[i]-1; 42 ull haha=gthsh(ch[i]+1,ch[i+1]-1); 43 while(1){ 44 if(st+length-1>end)return false; 45 if(t.gthsh(st,st+length-1)==haha){ 46 st+=length; 47 break; 48 } 49 ++st; 50 } 51 } 52 return true; 53 } 54 }str[maxn]; 55 inline void PP(){ 56 bs[0]=1; 57 for(int i=1;i<=maxl;i++) 58 bs[i]=bs[i-1]*BASE; 59 } 60 inline void CLR(){ 61 for(int i=1;i<=n;i++) 62 str[i].clr(); 63 } 64 bool judge(){ 65 ull tmp=0; 66 int lst=0; 67 for(int i=1;i<=n;i++) 68 if(!str[i].cc){ 69 if(!lst)tmp=str[i].hsh[str[i].len],lst=i; 70 else{ 71 if(str[i].hsh[str[i].len]!=tmp)return false; 72 } 73 } 74 if(lst){ 75 for(int i=1;i<=n;i++) 76 if(str[i].cc) 77 if(!str[i].pipi(str[lst])) 78 return false; 79 } 80 else{ 81 flag=true; 82 sort(str+1,str+1+n); 83 for(int i=1;i<n;i++) 84 if(str[i].gthsh(1,str[i].ch[1]-1)!=str[i+1].gthsh(1,str[i].ch[1]-1)) 85 return false; 86 flag=false; 87 sort(str+1,str+1+n); 88 for(int i=1;i<n;i++){ 89 int sur=str[i].len-str[i].ch[str[i].cc]; 90 if(str[i].gthsh(str[i].ch[str[i].cc]+1,str[i].len)!=str[i+1].gthsh(str[i+1].len-sur+1,str[i+1].len)) 91 return false; 92 } 93 } 94 return true; 95 } 96 int main(){ 97 ios::sync_with_stdio(false); 98 PP(); 99 cin>>T; 100 while(T--){ 101 cin>>n; 102 CLR(); 103 string tmp; 104 for(int i=1;i<=n;i++){ 105 cin>>tmp; 106 str[i].gthsh(tmp); 107 } 108 puts(judge()?"Y":"N"); 109 } 110 return 0; 111 }