「NOI2018」你的名字

#include<bits/stdc++.h>
#define N 2000011
#define LL long long
#define Mid (l+r>>1)
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)
using namespace std;
int ls[N*20],rs[N*20],sz[N*20],size=1,n,last=1,siz;
char S[N];
inline void ins(int &now,int l,int r,int pos){
    if (!now) now=++siz;
    if (l==r) return (void) (sz[now]++);
    if (pos<=Mid) ins(ls[now],l,Mid,pos);
    else ins(rs[now],Mid+1,r,pos);
    sz[now]=sz[ls[now]]+sz[rs[now]];
}
int merge(int x,int y,int l,int r){
    if (!x||!y) return x+y;
    int o=++siz;
    if (l==r) sz[o]=sz[x]+sz[y];
    else {
        ls[o]=merge(ls[x],ls[y],l,Mid);
        rs[o]=merge(rs[x],rs[y],Mid+1,r);
        sz[o]=sz[ls[o]]+sz[rs[o]];
    } return o;
}
int query(int u,int l,int r,int pos){
    if (!sz[u]) return 0;
    if (l==r) return l;
    if (pos<=Mid) return query(ls[u],l,Mid,pos);
    int ran=query(rs[u],Mid+1,r,pos);
    return ran?ran:query(ls[u],l,Mid,pos);
}
vector<int> g[N],v;
int fa[N],ch[N][26],mx[N],mi[N],rt[N],dep[N],vis[N];
void add(){
    for (int i=2;i<=size;i++) g[fa[i]].push_back(i);
}
void dfs(int x){
    for(int i=g[x].size()-1;~i;i--) {
        dfs(g[x][i]),rt[x]=merge(rt[x],rt[g[x][i]],1,n);
        mx[x]=Max(mx[x],mx[g[x][i]]); mi[x]=Min(mi[x],mi[g[x][i]]);
    } 
}
void pre(int x,int ff,int pos){
    int np=++size;
    dep[np]=dep[last]+1; 
    if (ff) v.push_back(np); else {
        ins(rt[np],1,n,pos);
        mx[np]=mi[np]=pos;
    }
    for (;last&&!ch[last][x];last=fa[last]) ch[last][x]=np;
    if (!last) return (void) (fa[np]=1,last=np);
    int q=ch[last][x];
    if (dep[last]+1==dep[q]) return (void) (fa[np]=q,last=np);
    int nq=++size; dep[nq]=dep[last]+1;
//    assert(dep[])
    fa[nq]=fa[q]; fa[np]=fa[q]=nq; 
    if (ff) rt[nq]=rt[q],mx[nq]=mx[q],mi[nq]=mi[q];
    memcpy(ch[nq],ch[q],sizeof ch[q]);
    for (;last&&ch[last][x]==q;last=fa[last]) ch[last][x]=nq;
    last=np;
//    cerr<<"kk"<<size<<endl;
}
LL calc(char *s,int l,int r){
    last=1; v.clear();
    LL len=strlen(s),ans=0,all=0;
    for (int i=0;i<len;i++) 
     pre(s[i]-'a',1,0);
//    cerr<<size<<endl;
    for (int i=0;i<v.size();i++) {
        for (int p=v[i];p>1;p=fa[p]) {
            if (vis[p]) break; 
            all+=dep[p]-dep[fa[p]],vis[p]=1;
            if (rt[p]) {
                if ((l==1&&r==n)) { ans+=dep[p]-dep[fa[p]]; continue;}
                if (mx[p]<l||mi[p]>r) continue;
                int mxlen= (mx[p]<=r)?mx[p]-l+1:query(rt[p],1,n,r)-l+1;
                if (mxlen>dep[fa[p]]) ans+=Min(dep[p],mxlen)-dep[fa[p]];
            }
        }
    }
     for(int i=0;i<v.size();i++){
        for(int p=v[i];p>1;p=fa[p]){
            if(!vis[p]) break; vis[p] = 0;
        }
    }
//    cerr<<all<<' '<<ans<<endl;
    return all - ans;
}
int q,l,r,pos[N];
LL ans;
signed main () {
    freopen("name.in","r",stdin);
    freopen("name.out","w",stdout);
    scanf("%s",S+1); n=strlen(S+1);
    for(int i=1;i<=n;i++) pre(S[i]-'a',0,i);
        add(),dfs(1);
    scanf("%d",&q);
    while (q--) {
        scanf("%s",S+1); scanf("%d%d",&l,&r);
        printf("%lld
",calc(S+1,l,r));        
    }
    return 0;
}
原文地址:https://www.cnblogs.com/rrsb/p/9489550.html