• 十二省联考2019 字符串问题


    十二省联考2019 字符串问题


    只要有点码力,想明白再写,考场上应该写的出来

    首先可以想到,对每个(A_i)建一个点,如果(A_i)后面可以接(A_j),就连一条边(A_i ightarrow A_j),那么设(A_i)的点权是(|A_i|),跑一个最长链就能解决。

    那么根据题意又可以这样连,如果(A_i)支配(B_j),连一条边(A_i ightarrow B_j);如果(B_i)(A_j)的前缀,连一条边(B_i ightarrow A_j)

    第一种边显然是(O(n))级别的,那么要优化第二种边

    显然想到sam,如果(B)(A)的前缀,那么先把串变成反串,就等价于在sam的parent树上,(B)(A)的父亲,且(B.lengthleq A.length)

    (这题部分分还是很足的,不考虑(B.lengthleq A.length)有80分,很nb)

    所以可以直接用parent树优化连边,现在只剩下一个问题就是(B.lengthleq A.length)怎么处理

    把sam上每个点建个map,大暴力建一条链,就做完了

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    typedef long long ll;
    il ll gi(){
        ll x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    char S[200010];
    int la[200010],ra[200010],lb[200010],rb[200010];
    int a[200010],b[200010];
    int fir[2000010],dis[50000010],nxt[50000010],id;
    il vd link(int a,int b){
        nxt[++id]=fir[b],fir[b]=id,dis[id]=a;
    }
    int trans[400010][26],slink[400010],len[400010],cnt,lst,maxl[2000010];
    std::map<int,int>map[400010];
    il int newnode(){++cnt;memset(trans[cnt],0,sizeof trans[cnt]),slink[cnt]=len[cnt]=0;return cnt;}
    il int newnode(int from){++cnt;memcpy(trans[cnt],trans[from],sizeof trans[cnt]),slink[cnt]=slink[from],len[cnt]=len[from];return cnt;}
    int leaf[200010];
    il vd extend(int x,int i){
        int p=lst,np=newnode();lst=np;leaf[i]=np;len[np]=len[p]+1;
        while(p&&!trans[p][x])trans[p][x]=np,p=slink[p];
        if(!p)slink[np]=1;
        else{
            int q=trans[p][x];
            if(len[q]==len[p]+1)slink[np]=q;
            else{
                int nq=newnode(q);len[nq]=len[p]+1;
                slink[np]=slink[q]=nq;
                while(p&&trans[p][x]==q)trans[p][x]=nq,p=slink[p];
            }
        }
    }
    int st[19][400010];
    ll f[2000010];bool vis[2000010],ansisinf;
    bool instk[2000010];
    il vd dp(int x){
        if(vis[x])return;
        vis[x]=1;f[x]=0;instk[x]=1;
        for(int i=fir[x];i;i=nxt[i]){
            if(instk[dis[i]]){ansisinf=1;return;}
            if(!vis[dis[i]])dp(dis[i]);
            if(ansisinf)return;
            f[x]=std::max(f[x],f[dis[i]]);
        }
        f[x]+=maxl[x];instk[x]=0;
    }
    int sec[400010];
    int main(){
    #ifdef XZZSB
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        int orzyyb=gi(),x,y;
        while(orzyyb--){
            scanf("%s",S+1);
            int n=strlen(S+1);
            std::reverse(S+1,S+n+1);
            cnt=0;lst=newnode();
            for(int i=1;i<=n;++i)extend(S[i]-'a',i);
            int sam=cnt;
            for(int i=2;i<=sam;++i)st[0][i]=slink[i];
            for(int i=1;i<19;++i)for(int j=1;j<=sam;++j)st[i][j]=st[i-1][st[i-1][j]];
            int A=gi();
            for(int i=1;i<=A;++i){
                ra[i]=n-gi()+1,la[i]=n-gi()+1;
                x=leaf[ra[i]];
                for(int j=18;~j;--j)if(len[st[j][x]]>=ra[i]-la[i]+1)x=st[j][x];
                if(map[x].find(ra[i]-la[i]+1)==map[x].end())map[x][ra[i]-la[i]+1]=++cnt;
                a[i]=map[x][ra[i]-la[i]+1];
                link(a[i],++cnt);a[i]=cnt;
                maxl[a[i]]=ra[i]-la[i]+1;
            }
            int B=gi();
            for(int i=1;i<=B;++i){
                rb[i]=n-gi()+1,lb[i]=n-gi()+1;
                x=leaf[rb[i]];
                for(int j=18;~j;--j)if(len[st[j][x]]>=rb[i]-lb[i]+1)x=st[j][x];
                if(map[x].find(rb[i]-lb[i]+1)==map[x].end())map[x][rb[i]-lb[i]+1]=++cnt;
                b[i]=map[x][rb[i]-lb[i]+1];
            }
            for(int i=1;i<=sam;++i){
                int lst=i;
                for(auto j:map[i]){
                    if(lst)link(lst,j.second);
                    lst=j.second;
                }
                link(lst,sec[i]=++cnt);
            }
            for(int i=2;i<=sam;++i)link(sec[slink[i]],i);
            int m=gi();
            for(int i=1;i<=m;++i)x=gi(),y=gi(),link(a[x],b[y]);
            ansisinf=0;
            ll ans=0;
            for(int i=1;!ansisinf&&i<=cnt;++i)dp(i),ans=std::max(ans,f[i]);
            if(ansisinf)ans=-1;
            printf("%lld
    ",ans);
            id=0;memset(fir+1,0,4*cnt);
            for(int i=0;i<19;++i)memset(st[i]+1,0,4*sam);
            memset(vis+1,0,cnt);
            memset(instk+1,0,cnt);
            memset(maxl+1,0,4*cnt);
            for(int i=1;i<=sam;++i)map[i].clear();
            fflush(stdout);
        }
        return 0;
    }
    
  • 相关阅读:
    new 做了什么
    create-react-app+react-app-rewired引入antd实践
    实战build-react(二)-------引入Ant Design(增加)
    package.json文件
    读书多些会怎样
    关于学历
    QDialog弹出一个窗口,改变窗口大小
    #include <thread>
    #include <memory>
    #include <map>
  • 原文地址:https://www.cnblogs.com/xzz_233/p/10693190.html
Copyright © 2020-2023  润新知