MnZn 求助线段树
查看原帖
MnZn 求助线段树
420129
Nt_Tsumiki楼主2024/7/8 19:10

rt WA#8 输出的很大

实在不会写拍子(

#include <iostream>
#include <cstdio>
#include <string>

#define N 200001

using namespace std;
int n;
string s,T;

int tcnt,rt[N];
struct Tree { int mx,id,ls,rs; }t[N<<6];

Tree pushup(Tree a,Tree b) {
    Tree res;
    if (a.mx>=b.mx) res.mx=a.mx,res.id=a.id;
    else res.mx=b.mx,res.id=b.id;
    return res;
}

void upd(int &x,int l,int r,int pos) {
    if (!x) t[x=++tcnt]={0,l,0,0};
    if (l==r) return t[x].mx=1,t[x].id=l,void();
    int mid=(l+r>>1);
    if (pos<=mid) upd(t[x].ls,l,mid,pos);
    else upd(t[x].rs,mid+1,r,pos);
    if (t[t[x].ls].mx>=t[t[x].rs].mx and t[x].ls) t[x].mx=t[t[x].ls].mx,t[x].id=t[t[x].ls].id;
    else if (t[x].rs) t[x].mx=t[t[x].rs].mx,t[x].id=t[t[x].rs].id;
}

int merge(int x,int y,int l,int r) {
    if (!x or !y) return x|y;
    int rt=++tcnt; t[rt]={0,l,0,0};
    if (l==r) return t[rt]={t[x].mx+t[y].mx,l,0,0},rt;
    int mid=(l+r>>1);
    t[rt].ls=merge(t[x].ls,t[y].ls,l,mid);
    t[rt].rs=merge(t[x].rs,t[y].rs,mid+1,r);
    if (t[t[rt].ls].mx>=t[t[rt].rs].mx and t[rt].ls) t[rt].mx=t[t[rt].ls].mx,t[rt].id=t[t[rt].ls].id;
    else if (t[rt].rs) t[rt].mx=t[t[rt].rs].mx,t[rt].id=t[t[rt].rs].id;
    return rt;
}

Tree ask(int x,int l,int r,int L,int R) {
    if (!x) return {0,l,0,0};
    if (L<=l and r<=R) return t[x];
    int mid=(l+r>>1);
    if (R<=mid) return ask(t[x].ls,l,mid,L,R);
    else if (L>mid) return ask(t[x].rs,mid+1,r,L,R);
    else return pushup(ask(t[x].ls,l,mid,L,R),ask(t[x].rs,mid+1,r,L,R));
}

int tot=1,np=1,ch[N][26],fail[N],len[N];

void ins(int c,int id) {
    int p=np; len[np=++tot]=len[p]+1;
    upd(rt[np],1,n,id);
    while (p and !ch[p][c]) ch[p][c]=np,p=fail[p];
    if (!p) fail[np]=1;
    else {
        int q=ch[p][c];
        if (len[q]==len[p]+1) fail[np]=q;
        else {
            int nq=++tot;
            len[nq]=len[p]+1,fail[nq]=fail[q];
            fail[q]=fail[np]=nq;
            memcpy(ch[nq],ch[q],sizeof ch[q]);
            while (p and ch[p][c]==q) ch[p][c]=nq,p=fail[p];
        }
    }
}

int cnt,head[N],fa[N][21];
struct Node { int to,nxt; }e[N];

void add(int u,int v) { e[++cnt]=Node{v,head[u]},head[u]=cnt; }

void dfs0(int u) {
    fa[u][0]=fail[u];
    for (int i=1;i<=20;i++) fa[u][i]=fa[fa[u][i-1]][i-1];
    for (int i=head[u];i;i=e[i].nxt) {
        int v=e[i].to;
        dfs0(v);
        rt[u]=merge(rt[u],rt[v],1,n);
    }
}

int pos[N],ans[N];

int main() {
    cin>>s; s=" "+s;
    scanf("%d",&n);
    for (int i=1;i<=n;i++) {
        cin>>T; np=1;
        for (char c:T) ins(c-'a',i);
    }
    for (int i=2;i<=tot;i++) add(fail[i],i);
    dfs0(1); int Len=s.size(),p=1,res=0;
    for (int i=1;i<Len;i++) {
        if (ch[p][s[i]-'a']) res++,p=ch[p][s[i]-'a'];
        else {
            while (p and !ch[p][s[i]-'a']) p=fail[p];
            if (p) res=len[p]+1,p=ch[p][s[i]-'a'];
            else res=0,p=1;
        }
        ans[i]=res,pos[i]=p;
    }
    int q; scanf("%d",&q);
    for (int i=1,l,r,l0,r0;i<=q;i++) {
        scanf("%d%d%d%d",&l0,&r0,&l,&r);
        if (r-l+1>ans[r]) {
            printf("%d 0\n",l0);
            continue;
        }
        int p=pos[r];
        for (int i=20;i>=0;i--)
            while (len[fa[p][i]]>=r-l+1) p=fa[p][i];
        Tree res=ask(rt[p],1,n,l0,r0);
        printf("%d %d\n",res.mx==0?l0:res.id,res.mx);
    }
    return 0;
}
2024/7/8 19:10
加载中...