Topic: given n target strings and M-mode strings, ask how many of these m pattern strings each appear in the target string, and N target string each with a maximum number of pattern strings as substrings
I was wrong...... Even with the fail tree +set heuristic merging is not optimized to O (nlog^2n) ... The data range of the problem is quite non-solvable.
First, all the names and name strings are inserted into the AC automata.
Put a set on each point to record the name of the cat that this point is prefixed with
Then build a fail tree along the fail tree from bottom to top heuristic merging
Every time a point is merged, if this point is a string of names, then the cat named at this point is the one with all the elements in the set.
The statistical answer is clearly O (nlog^2n) But the statistical answer here still does not avoid high complexity
Final complexity of O (nlog^2n+σans2) where Ans2 is the answer to the second question
Feel the bottleneck of this algorithm is on the σans2 ... Maybe we could take a different approach. Statistic Ans2? Feel...... It is not necessary to look ...
#include <set> #include <map> #include <vector> #include <cstdio> #include <cstring># Include <iostream> #include <algorithm> #define M 200200using namespace Std;struct trie{trie *fail;map< int,trie*> son;set<int> s;vector<trie*> fail_son;int ed,cnt;} *root,mempool[m],*c=mempool;int n,m,ans1[50500],ans2[20200];int substitute[50500];void Insert (Trie* &p,int left , int pos,bool flag) {if (!p) p=c++;if (!flag) P->s.insert (POS); if (!left) {if (flag) {if (p->ed) substitute[p->ed] =pos;p->ed=pos;p->cnt++;} return;} int temp;scanf ("%d", &temp); Insert (P->son[temp],left-1,pos,flag);} void Build_tree () {static Trie *q[m];static int r,h;map<int,trie*>::iterator it;for (it=root->son.begin (); it! =root->son.end (); it++) {it->second->fail=root;root->fail_son.push_back (it->second); q[++r]=it- >second;} while (r!=h) {Trie *p=q[++h];for (It=p->son.begin (); It!=p->son.end (); it++) {Trie *temp=p->fail;while (temp!= root&&!temp->son[it->first]) temp=temp->fail;if (Temp->son[it->first]) temp=temp->son[it-> First];it->second->fail=temp;temp->fail_son.push_back (It->second); q[++r]=it->second;}} void DFS (Trie *p) {vector<trie*>::iterator it;set<int>::iterator _it;for (It=p->fail_son.begin (); it!= P->fail_son.end (); it++) {DFS (*it); set<int>&s=p->s;set<int>&son_s= (*it)->s;if ( S.size () <son_s.size ()) swap (s,son_s); for (_it=son_s.begin (); _it!=son_s.end (); _it++) S.insert (*_it); son_s.clear ();} if (p->ed) {ans1[p->ed]=p->s.size (); for (_it=p->s.begin (); _it!=p->s.end (); _it++) ans2[*_it]+=p-> CNT;}} int main () {int i,x;cin>>n>>m;for (i=1;i<=n;i++) {scanf ("%d", &x), Insert (root,x,i,0); scanf ("%d", &X); Insert (root,x,i,0);} for (i=1;i<=m;i++) {scanf ("%d", &x); Insert (root,x,i,1);} Build_tree ();D FS (root), for (i=m;i;i--) if (Substitute[i]) ans1[i]=ans1[substitute[i]];for (i=1;i<=m;i++) printf (" %d\n ", Ans1[i]); for (i=1;i<=n;i++) printf ("%d%c", ans2[i],i==n? \ n ': '); return 0;}
Bzoj 2754 SCOI2012 Meow on the planet's name fail tree +set heuristic merge