抄卡组

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 }
View Code

 

posted @ 2016-01-08 09:57  Ngshily  阅读(226)  评论(0编辑  收藏  举报