BZOJ3881 [Coci2015]Divljak
字符串题!
考虑严格匹配的话肯定就是ACA辣
发现求的其实就是Fail树上的子树和
具体加一个串的话是Fail树上树链的并
那么就套板子辣
vector用unique不会自动resize的...我是憨憨= =
而unique以后后面是乱序就导致了WA...
(沃日不对啊我是多项式选手我怎么到处写数据结构)
//Love and Freedom. #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define ll long long #define inf 20021225 #define N 2000010 #define lowbit(x) (x&-x) using namespace std; int read() { int s=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return f*s; } struct bit { int t[N],n=N-8; void add(int x,int v){while(x<=n) t[x]+=v,x+=lowbit(x);} int query(int x){int v=0; while(x) v+=t[x],x-=lowbit(x); return v;} int ask(int l,int r){return query(r)-query(l-1);} }b; //bit int ch[N][26],fail[N],tag[N],rt=1,poi=1; // ACA struct edge{int to,lt;}e[N]; int in[N],cnt,dfn[N],idfn[N],tms,fa[N][21],sz[N],dep[N]; // fail //----------fail----------- void add(int x,int y){fail[y]=x; e[++cnt].to=y; e[cnt].lt=in[x]; in[x]=cnt;} void dfs(int x) { sz[x]=1; dfn[x]=++tms; idfn[tms]=x; for(int i=1;i<20;i++) fa[x][i]=fa[fa[x][i-1]][i-1]; for(int i=in[x];i;i=e[i].lt) { int y=e[i].to; dep[y]=dep[x]+1; fa[y][0]=x; dfs(y); sz[x]+=sz[y]; } } int LCA(int x,int y) { if(dep[x]<dep[y]) swap(x,y); int len=dep[x]-dep[y]; for(int i=0;i<20;i++) if(len>>i&1) x=fa[x][i]; if(x==y) return x; for(int i=19;~i;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } //-------------ACA------------ void insert(char c[],int n,int id) { int pos=rt; for(int i=1;i<=n;i++) { int son=c[i]-'a'; if(!ch[pos][son]) ch[pos][son]=++poi; pos=ch[pos][son]; } tag[id]=pos; } #include<queue> queue<int> q; void build() { for(int i=0;i<26;i++) if(ch[rt][i]) add(rt,ch[rt][i]),q.push(ch[rt][i]); else ch[rt][i]=rt; while(!q.empty()) { int pos=q.front(); q.pop(); for(int i=0;i<26;i++) if(ch[pos][i]) add(ch[fail[pos]][i],ch[pos][i]),q.push(ch[pos][i]); else ch[pos][i]=ch[fail[pos]][i]; } } //---------insert---------- #include<vector> #define pb push_back vector<int> vec; void match(char c[],int n) { int pos=rt; vec.clear(); for(int i=1;i<=n;i++) pos=ch[pos][c[i]-'a'],vec.pb(dfn[pos]); sort(vec.begin(),vec.end()); //vec.erase(unique(vec.begin(),vec.end()),vec.end()); } char w[N]; void solve() { scanf("%s",w+1); int len=strlen(w+1); match(w,len); for(int i=0;i<vec.size();i++) { b.add(vec[i],1); if(i) b.add(dfn[LCA(idfn[vec[i]],idfn[vec[i-1]])],-1); } } //----------query----------- int query(int id) { int pos=tag[id]; return b.ask(dfn[pos],dfn[pos]+sz[pos]-1); } //---------main---------- int main() { int n=read(); for(int i=1;i<=n;i++) { scanf("%s",w+1); int len=strlen(w+1); insert(w,len,i); } build(); dfs(1); int q=read(); while(q--) { int opt=read(),id; if(opt==1) solve(); else id=read(),printf("%d\n",query(id)); } return 0; }