• 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
    ",query(id));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    WebView与 JS 交互方式
    ES6常用知识点
    Flash Builder 破解与开发环境配置
    如何修改默认浏览器
    基本数据类型和常用内建对象
    VS 2010 使用技巧
    javascript之事件驱动编程的几个基本概念
    javascript笔记之DHTML基础
    浏览器对象模型
    开发心得记录
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/11648758.html
Copyright © 2020-2023  润新知