其他分享
首页 > 其他分享> > G. Death DBMS(查询每个主串和n个模板串匹配后val最大值,支持单点更新)

G. Death DBMS(查询每个主串和n个模板串匹配后val最大值,支持单点更新)

作者:互联网

题:https://codeforces.com/contest/1437/problem/G

题意:首先给定n个模式串,每个模式串一开始价值为0,支持q个查询:

分析:

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
const int M=3e5+5;
int tr[M<<2];
const int maxn=26;
int trie[M][maxn],fail[M],las[M],sz[M],tp[M],son[M],id[M],dfn[M],rdfn[M],fa[M];
char s[M];
vector<int>g[M];
multiset<int>mx[M];
int tot;
struct AC{
    int cnt=0;
    void Insert(char buf[],int sign){
        int len=strlen(buf),now=0;
        for(int i=0;i<len;i++){
            int x=buf[i]-'a';
            if(!trie[now][x])
                trie[now][x]=++cnt;
            now=trie[now][x];
        }
        mx[now].insert(0);
        id[sign]=now;
    }
    void getfail(){
        queue<int>que;
        while(!que.empty()) que.pop();
        for(int i=0;i<maxn;i++)
            if(trie[0][i]){
                fail[trie[0][i]]=0;
                que.push(trie[0][i]);
            }
        while(!que.empty()){
            int now=que.front();
            que.pop();
            for(int i=0;i<maxn;i++)
                if(trie[now][i]){
                    fail[trie[now][i]]=trie[fail[now]][i];
                    que.push(trie[now][i]);
                }
                else
                    trie[now][i]=trie[fail[now]][i];
        }
    }
}ac;
void dfs1(int u,int f){
    fa[u]=f,sz[u]=1;
    for(auto v:g[u]){
        if(v!=f){
            dfs1(v,u);
            sz[u]+=sz[v];
            if(!son[u]||sz[son[u]]<sz[v]) son[u]=v;
        }

    }
}
void dfs2(int u,int top){
    tp[u]=top;
    dfn[u]=++tot;
    rdfn[tot]=u;
    if(son[u])
        dfs2(son[u],top);
    for(auto v:g[u])
        if(v!=fa[u]&&v!=son[u])dfs2(v,v);
}
void up(int root){ tr[root]=max(tr[root<<1],tr[root<<1|1]); }
void build(int root,int l,int r){
    tr[root]=-1;
    if(l==r){
        tr[root]=*mx[rdfn[l]].rbegin();
        return ;
    }
    int midd=(l+r)>>1;
    build(lson);
    build(rson);
    up(root);
}
void update(int pos,int c,int root,int l,int r){
    if(l==r){
        tr[root]=c;
        return ;
    }
    int midd=(l+r)>>1;
    if(pos<=midd)
        update(pos,c,lson);
    else
        update(pos,c,rson);
    up(root);
}
int query(int L,int R,int root,int l,int r){
    if(L<=l&&r<=R){
        return tr[root];
    }
    int midd=(l+r)>>1;
    int res=-1;
    if(L<=midd) res=query(L,R,lson);
    if(R>midd) res=max(res,query(L,R,rson));
    return res;
}
int trquery(int u){
    int res=-1;
    while(tp[u]!=0){
        res=max(res,query(dfn[tp[u]],dfn[u],1,1,tot));
        u=fa[tp[u]];
    }
    res=max(res,query(dfn[0],dfn[u],1,1,tot));
    return res;
}
int solve(char buf[]){
    int len=strlen(buf),now=0;
    int ans=-1;
    for(int i=0;i<len;i++){
        now=trie[now][buf[i]-'a'];
        ans=max(ans,trquery(now));
    }
    return ans;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",s);
        ac.Insert(s,i);
    }
    ac.getfail();
    mx[0].insert(-1);
    for(int i=1;i<=ac.cnt;i++){
        g[fail[i]].pb(i);
        mx[i].insert(-1);
    }
    dfs1(0,-1);
    dfs2(0,0);
    build(1,1,tot);
    for(int i=1;i<=m;i++){
        int op;
        scanf("%d",&op);
        if(op==1){
            int x,val;
            scanf("%d%d",&x,&val);
            ///可能会出现相同的模式串,只要最大的那个
            ///更新时要记录上个更新值,用来下次更新时删除掉(也就是“覆盖”)
            mx[id[x]].erase(mx[id[x]].find(las[x]));
            las[x]=val;
            mx[id[x]].insert(las[x]);
            update(dfn[id[x]],*mx[id[x]].rbegin(),1,1,tot);
        }
        else{
            scanf("%s",s);
            printf("%d\n",solve(s));
        }
    }
    return 0;
}
View Code

 

标签:主串,DBMS,Death,int,res,dfn,fail,buf,节点
来源: https://www.cnblogs.com/starve/p/13899655.html