记录编号 447956 评测结果 AAAAAAAAAA
题目名称 循环同构 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 2.250 s
提交时间 2017-09-11 20:23:04 内存使用 442.82 MiB
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
string S[N],s;
int n,m,L,go[N][26],par[N],len[N],last,top;
int New(int L){len[++top]=L;return top;}
void extend(int w){
    int p=last,np=New(len[p]+1);
    while (p&&!go[p][w]) go[p][w]=np,p=par[p];
    if (!p) par[np]=1;
    else{
        int q=go[p][w];
        if (len[q]==len[p]+1) par[np]=q;
        else{
            int nq=New(len[p]+1);
            memcpy(go[nq],go[q],sizeof go[q]);
            par[nq]=par[q];
            par[np]=par[q]=nq;
            while (p&&go[p][w]==q) go[p][w]=nq,p=par[p];
        }
    }
    last=np;
}
vector<int> v[N];
int rank(int x,vector<int>& a){
    int l=0,r=a.size()-1;
    while (l<r){
        int mid=(l+r)>>1;
        if (x>a[mid+1]) l=mid+1;else r=mid;
    }
    return a.size()-l-1;
}
int cnt[N],size[N],val[N],q[N],dp[21][N],vis[N];
int gettop(int x,int h){
    for (int i=20;len[par[x]]>=h;x=dp[i][x])
        while (len[dp[i][x]]<h) i--;
    return x;
}
int main()
{
    freopen("rotate.in","r",stdin);
    freopen("rotate.out","w",stdout);
    cin.sync_with_stdio(false);
    cin>>s>>n;
    last=New(0);
    for (int i=1;i<=n;i++){
        cin>>S[i];
        last=1;
        for (int j=0;j<S[i].size();j++) extend(S[i][j]-'a');
        for (int j=0;j<S[i].size();j++) extend(S[i][j]-'a');
    }
    for (int i=0,p=1,now=0;i<s.size();i++){
        int w=s[i]-'a';
        while (p&&!go[p][w]) p=par[p],now=len[p];
        if (p) p=go[p][w],now++;else p=1;
        size[p]++;val[p]++;
        v[p].push_back(now);
    }
    for (int i=1;i<=top;i++) v[i].push_back(0),sort(v[i].begin(),v[i].end());
    for (int i=1;i<=top;i++) cnt[len[i]]++;
    for (int i=1;i<=top;i++) cnt[i]+=cnt[i-1];
    for (int i=1;i<=top;i++) q[cnt[len[i]]--]=i;
    for (int i=top;i;i--) size[par[q[i]]]+=size[q[i]];
    for (int i=1;i<=top;i++) dp[0][i]=par[i];
    for (int j=1;j<21;j++)
    for (int i=1;i<=top;i++)
        dp[j][i]=dp[j-1][dp[j-1][i]];
    for (int i=1;i<=n;i++){
        int p=1;
        for (int j=0;j<S[i].size();j++) p=go[p][S[i][j]-'a'];
        int ans=0;
        for (int j=0;j<S[i].size();j++){
            p=go[p][S[i][j]-'a'];
            int x=gettop(p,S[i].size());
            if (vis[x]==i) continue;
            vis[x]=i;
            ans+=(size[x]-val[x]+rank(S[i].size(),v[x]));
        }
        printf("%d\n",ans);
    }
    return 0;
}