• 【BZOJ3277】串


    题面

    http://darkbzoj.tk/problem/3277

    题解

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<set>
    #define N 100050
    #define ri register int
    using namespace std;
    int n,k;
    
    struct node{
      int ff,len;
      int ch[26];
      set<int> s;
    } t[N<<1];
    vector<int> son[N<<1];
    
    struct SAM {
      int cnt[N<<1];
      int last,tot;
      void init(){
        last=tot=1;
      }
      int extend(int p,int c,int id) {
        int np;
        {
          np=++tot;
          t[np].len=t[p].len+1;
          while (p && !t[p].ch[c]) t[p].ch[c]=np,p=t[p].ff;
          if (!p) {
            t[np].ff=1;
          }
          else {
            int q=t[p].ch[c];
            if (t[q].len==t[p].len+1) {
              t[np].ff=q;
            }
            else {
              int nq=++tot;
              t[nq]=t[q]; t[nq].len=t[p].len+1;
              t[np].ff=t[q].ff=nq;
              while (p && t[p].ch[c]==q) t[p].ch[c]=nq,p=t[p].ff;
            }
          }
        }
        t[np].s.insert(id);
        return np;
      }
      void maketree() {
        for (ri i=1;i<=tot;i++) son[t[i].ff].push_back(i);
      }
      void merge(int x) {
        for (ri i=0,l=son[x].size();i<l;i++) {
          merge(son[x][i]);
          set<int> :: iterator it;
          for (it=t[son[x][i]].s.begin();it!=t[son[x][i]].s.end();++it) t[x].s.insert(*it);
        }
      }
    } sam;
    
    string s[N];
    
    int main(){
      ios::sync_with_stdio(false);
      cin>>n>>k;
      sam.init();
      for (ri i=1;i<=n;i++) {
        cin>>s[i];
        int p=1;
        for (ri j=0,l=s[i].size();j<l;j++) p=sam.extend(p,s[i][j]-'a',i);
      }
      sam.maketree();
      sam.merge(1);
      for (ri i=1;i<=n;i++) {
        int cnt=0;long long ans=0;
        int now=1;
        for (ri j=0,l=s[i].size();j<l;j++) {
          if (t[t[now].ch[s[i][j]-'a']].s.size()>=k) {
            cnt++;
            now=t[now].ch[s[i][j]-'a'];
            ans+=cnt;
          }
          else {
            while (now && t[t[now].ch[s[i][j]-'a']].s.size()<k) now=t[now].ff;
            if (!now) {
              cnt=0; now=1;
            }
            else {
              cnt=t[now].len+1;
              now=t[now].ch[s[i][j]-'a'];
              ans+=cnt;
            }
          }
        }
        cout<<ans<<" ";
      }
      return 0;
    }
  • 相关阅读:
    第二次:Ubuntu16.04 安装Docker
    第一次:从今开始玩Linux,Ubuntu16.04
    学习日常
    Vector和ArrayList的异同、Hashtable和HashMap的异同
    如何吃透Python的面向对象(OOP)
    Python基础(下篇)
    Python基础(中篇)
    Python基础(上篇)
    Pycharm安装
    Python的安装与配置
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279222.html
Copyright © 2020-2023  润新知