脑残错误调了将近一小时……这人没救了
……
其实跟bzoj3881差不多,建出AC自动机之后跑树链的并即可。因为只要出现姓或名就算一次,因此要把两次匹配得到的所有点一起做树链的并。
1 /************************************************************** 2 Problem: 2754 3 User: hzoier 4 Language: C++ 5 Result: Accepted 6 Time:1048 ms 7 Memory:24460 kb 8 ****************************************************************/ 9 #include<cstdio> 10 #include<cstring> 11 #include<stdint.h> 12 #include<algorithm> 13 #include<vector> 14 #include<map> 15 using namespace std; 16 const int maxn=200010; 17 int insert(const int*,int); 18 void getfail(); 19 void bfs(); 20 int LCA(int,int); 21 void match(const vector<int>&,int); 22 bool cmp(int,int); 23 map<int,int>ch[maxn]; 24 int f[maxn],q[maxn],val[maxn],d[maxn],cnt=0; 25 int dfn[maxn],size[maxn],son[maxn],top[maxn],sum[maxn]={0},a[maxn]; 26 vector<int>str1[maxn],str2[maxn]; 27 int n,m,s[maxn],len1[maxn],len2[maxn],iter[maxn],ans[maxn]; 28 int main(){ 29 scanf("%d%d",&n,&m); 30 for(int i=1;i<=n;i++){ 31 scanf("%d",&len1[i]); 32 for(int j=0;j<len1[i];j++)scanf("%d",&s[j]); 33 str1[i]=vector<int>(s,s+len1[i]); 34 scanf("%d",&len2[i]); 35 for(int j=0;j<len2[i];j++)scanf("%d",&s[j]); 36 str2[i]=vector<int>(s,s+len2[i]); 37 } 38 for(int i=1,len;i<=m;i++){ 39 scanf("%d",&len); 40 for(int j=0;j<len;j++)scanf("%d",&s[j]); 41 iter[i]=insert(s,len); 42 } 43 getfail(); 44 bfs(); 45 for(int i=1;i<=n;i++){ 46 a[0]=0; 47 match(str1[i],len1[i]); 48 match(str2[i],len2[i]); 49 sort(a+1,a+a[0]+1,cmp); 50 sum[a[1]]++; 51 ans[i]+=val[a[1]]; 52 for(int j=2,x;j<=a[0];j++){ 53 sum[a[j]]++; 54 ans[i]+=val[a[j]]; 55 x=LCA(a[j],a[j-1]); 56 sum[x]--; 57 ans[i]-=val[x]; 58 } 59 } 60 for(int i=cnt;i;i--)sum[f[q[i]]]+=sum[q[i]]; 61 for(int i=1;i<=m;i++)printf("%d ",sum[iter[i]]); 62 for(int i=1;i<=n;i++){ 63 if(i>1)printf(" "); 64 printf("%d",ans[i]); 65 } 66 return 0; 67 } 68 int insert(const int *a,int n){ 69 int x=0; 70 for(int i=0;i<n;i++){ 71 if(!ch[x].count(a[i]))ch[x][a[i]]=++cnt; 72 x=ch[x][a[i]]; 73 } 74 val[x]++; 75 return x; 76 } 77 void getfail(){ 78 int x,head=1,tail=1; 79 for(map<int,int>::iterator it=ch[x].begin();it!=ch[x].end();it++)q[tail++]=it->second; 80 d[0]=1; 81 while(head!=tail){ 82 x=q[head++]; 83 d[x]=d[f[x]]+1; 84 val[x]+=val[f[x]]; 85 for(map<int,int>::iterator it=ch[x].begin();it!=ch[x].end();it++){ 86 int y=f[x]; 87 while(y&&!ch[y].count(it->first))y=f[y]; 88 f[it->second]=(ch[y].count(it->first)?ch[y][it->first]:0); 89 q[tail++]=it->second; 90 } 91 } 92 } 93 void bfs(){ 94 fill(son,son+cnt+1,cnt+1); 95 for(int i=cnt,x;i;i--){ 96 x=q[i]; 97 dfn[x]=size[f[x]]; 98 size[x]++; 99 size[f[x]]+=size[x]; 100 if(size[x]>size[son[f[x]]])son[f[x]]=x; 101 } 102 for(int i=1,x;i<=cnt;i++){ 103 x=q[i]; 104 dfn[x]+=dfn[f[x]]+1; 105 if(x==son[f[x]])top[x]=top[f[x]]; 106 else top[x]=x; 107 } 108 } 109 int LCA(int x,int y){ 110 while(top[x]!=top[y]){ 111 if(d[top[x]]<d[top[y]])swap(x,y); 112 x=f[top[x]]; 113 } 114 return d[x]<d[y]?x:y; 115 } 116 void match(const vector<int>&str,int n){ 117 int x=0; 118 for(int i=0;i<n;i++){ 119 while(x&&!ch[x].count(str[i]))x=f[x]; 120 if(ch[x].count(str[i]))x=ch[x][str[i]]; 121 a[++a[0]]=x; 122 } 123 } 124 bool cmp(int x,int y){return dfn[x]<dfn[y];}