• 【CF235C】Cyclical Quest


    题面

    https://www.luogu.org/problem/CF235C

    题解

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<vector>
    #define ri register int
    #define N 1000500
    
    using namespace std;
    vector<int> son[N<<1];
    bool vis[N<<1];
    char s[N];
    string ss;
    int L0;
    
    struct SAM{
      int ff[N<<1],len[N<<1];
      int ch[N<<1][26];
      int cnt[N<<1];
      int las,tot;
      int stk[N<<1],top;
      void init() {
        las=tot=1;
      }
      void extend(int c) {
        int np=++tot,p=las; las=np; len[np]=len[p]+1;
        while (p && !ch[p][c]) ch[p][c]=np,p=ff[p];
        cnt[np]++;
        if (!p) ff[np]=1;
        else {
          int q=ch[p][c];
          if (len[q]==len[p]+1) ff[np]=q;
          else {
            int nq=++tot;
            for (ri i=0;i<26;i++) ch[nq][i]=ch[q][i]; ff[nq]=ff[q];
            len[nq]=len[p]+1;
            ff[np]=ff[q]=nq;
            while (p && ch[p][c]==q) ch[p][c]=nq,p=ff[p];
          }
        }
      }
      void maketree() {
        for (ri i=1;i<=tot;i++) son[ff[i]].push_back(i);
      }
      void treedp(int x){
        for (ri i=0;i<son[x].size();i++) {
          treedp(son[x][i]);
          cnt[x]+=cnt[son[x][i]];
        }
      }
      long long solve() {
        long long ret=0;
        int cc=0,now=1; top=0;
        for (ri i=0,l=ss.size();i<l-1;i++) {
          int c=ss[i]-'a';
          if (ch[now][c]) {
            cc++;
            now=ch[now][c];
            if (cc>=L0) {
              if (!vis[now]) vis[now]=1,ret+=cnt[now],stk[++top]=now;
              while (now!=1 && len[ff[now]]>=L0-1) now=ff[now]; cc=len[now];
            }
          }
          else {
            while (now && !ch[now][c]) now=ff[now];
            if (!now) {
              now=1; cc=0;
            }
            else {
              cc=len[now]+1;
              now=ch[now][c];
              if (cc>=L0) {
                if (!vis[now]) vis[now]=1,ret+=cnt[now],stk[++top]=now;
                while (now!=1 && len[ff[now]]>=L0-1) now=ff[now]; cc=len[now];
              }
            }
          }
        }
        for (ri i=top;i>=1;i--) vis[stk[i]]=0; vis[1]=0;
        return ret;
      }
    } sam;
    
    int n,m;
    int stk[N<<4],top;
    int main(){
      sam.init();
      scanf("%s",s);
      for (ri i=0,l=strlen(s);i<l;i++) sam.extend(s[i]-'a');
      sam.maketree();
      sam.treedp(1);
      scanf("%d",&n);
      for (ri i=1;i<=n;i++) {
        cin>>ss; L0=ss.size();
        ss=ss+ss;
        cout<<sam.solve()<<endl;
      }
    }
  • 相关阅读:
    MySQL query_cache_type 详解
    MySQL validate_password 插件
    MySQL冷备份的跨操作系统还原
    MySQL5.7新特性笔记
    MySQL参数详解
    保存mysql用户的登录信息到~.my.cnf文件;用于方便登录操作。
    MySQL应用层传输协议分析
    python egg
    MySQL 加锁处理分析
    train_test_split, 关于随机抽样和分层抽样
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279296.html
Copyright © 2020-2023  润新知