zoukankan      html  css  js  c++  java
  • 2018.12.24-3881-[Coci2015]Divljak

    算法标签:AC自动机

    思路:

    我们可以先把所有s串在AC 自动机上跑一遍,考虑如果一个串出现了,则我所能指向的所有fail节点都可以获得贡献,于是我们建出一棵fail树。

    接下来考虑把T串加入,自己思考我们发现如果只是单纯把我到根节点的路径权值都+1,我们可能会重复计算答案,于是就要树链合并,即按照dfs序排序后,每一只修改我和上一个点的lca到我的路径,就不会重复。有点卡空间,我的做法是lca用线段树维护区间d最小值找出lca,时间(常数大)换空间了。

    没有强制在线所以可以用AC自动机写,如果强制在线bzoj2555,就只能用数据结构套数据结构维护了,可怕。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=3e6+5,M=1e5+5;
    char s[N];queue<int> q;
    int minn[N<<2],ch[N][26],n,Q,tot=1,head[N],ne[N],to[N],num[N<<1],id[N],kk;
    int que[N],nt,g[N],d[N],cnt,dfn[N],sz[N],a[N],fail[N],idx;
    il int read(){int x;char ch;_(!);x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return x;}
    il void insert(int x,int y){ne[++cnt]=head[x];head[x]=cnt;to[cnt]=y;}
    bool cmp(int t1,int t2){return dfn[t1]<dfn[t2];}
    il void add(int x,int v){for(;x<=tot;x+=x&-x)g[x]+=v;}
    il int query(int x){int ans=0;for(;x;x-=x&-x)ans+=g[x];return ans;}
    il int Min(int x,int y){return d[x]<d[y]?x:y;}
    il int ins(){
        int l=strlen(s+1);int x=1;
        for(int i=1;i<=l;i++){
            if(!ch[x][s[i]-'a'])ch[x][s[i]-'a']=++tot;
            x=ch[x][s[i]-'a'];
        }
        return x;
    }
    il void dfs(int x){
        dfn[x]=++idx;sz[x]=1;num[id[x]=++kk]=x;
        for(int i=head[x];i;i=ne[i]){
            d[to[i]]=d[x]+1;dfs(to[i]);
            sz[x]+=sz[to[i]];num[++kk]=x;
        }
    }
    il void build(int x,int l,int r){
        if(l==r){minn[x]=num[l];return;}
        int mid=(l+r)>>1;
        build(x<<1,l,mid);build(x<<1|1,mid+1,r);
        minn[x]=Min(minn[x<<1],minn[x<<1|1]);
    }
    il int qm(int x,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return minn[x];
        int mid=(l+r)>>1;
        if(qr<=mid)return qm(x<<1,l,mid,ql,qr);
        else if(mid<ql)return qm(x<<1|1,mid+1,r,ql,qr);
        else return Min(qm(x<<1,l,mid,ql,qr),qm(x<<1|1,mid+1,r,ql,qr));
    }
    il int Lca(int x,int y){
        int l=id[x],r=id[y];if(l>r)swap(l,r);
        return qm(1,1,kk,l,r);
    }
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++){scanf(" %s",s+1);a[i]=ins();}
        q.push(1);
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=0;i<26;i++){
                if(!ch[x][i])continue;
                int tmp=fail[x];
                while(tmp>1&&!ch[tmp][i])tmp=fail[tmp];
                if(ch[tmp][i])fail[ch[x][i]]=ch[tmp][i];
                else fail[ch[x][i]]=1;q.push(ch[x][i]);
            }
        }
        for(int i=2;i<=tot;i++)insert(fail[i],i);
        d[1]=1;dfs(1);build(1,1,kk);int Q=read();
        while(Q--){
            int op=read();
            if(op==1){
                scanf(" %s",s+1);int l=strlen(s+1);
                int x=1,nt=0;que[++nt]=x;
                for(int i=1;i<=l;i++){
                    while(x!=1&&!ch[x][s[i]-'a'])x=fail[x];
                    if(ch[s[i]-'a'])x=ch[x][s[i]-'a'];que[++nt]=x;
                }
                sort(que+1,que+1+nt,cmp);add(dfn[que[1]],1);
                for(int j=2;j<=nt;j++){
                    add(dfn[que[j]],1);
                    add(dfn[Lca(que[j],que[j-1])],-1);
                }
            }
            else{
                int x=a[read()];printf("%d
    ",query(dfn[x]+sz[x]-1)-query(dfn[x]-1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    [React] {svg, css module, sass} support in Create React App 2.0
    [NPM] npm check to update the dependencies
    [RxJS] `add` Inner Subscriptions to Outer Subscribers to `unsubscribe` in RxJS
    [RxJS] Implement RxJS `concatMap` by Waiting for Inner Subscriptions to Complete
    [React] PureComponent in React
    [RxJS] Implement RxJS `switchMap` by Canceling Inner Subscriptions as Values are Passed Through
    [RxJS] Implement RxJS `mergeMap` through inner Observables to Subscribe and Pass Values Through
    [RxJS] Chain RxJS Operators Together with a Custom `pipe` Function using Array.reduce
    [RxJS] Implement the `map` Operator from Scratch in RxJS
    [RxJS] Create a Reusable Operator from Scratch in RxJS
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10171586.html
Copyright © 2011-2022 走看看