zoukankan      html  css  js  c++  java
  • 【TJOI2015】弦论

    题面

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

    题解

    // luogu-judger-enable-o2
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ri register int
    #define N 500050
    using namespace std;
    
    int les=0;
    char s[N];
    int n,t,k;
    
    struct SAM {
      int len[N<<1],ff[N<<1];
      int ch[N<<1][26];
      int cnt[N<<1];
      int tot,las;
      int sum[N<<1];
      int a[N<<1],ton[N<<1];
      void init() {
        tot=las=1;
      }
      void extend(int c) {
        int p=las,np=++tot; las=tot;
        len[np]=len[p]+1; cnt[np]++;
        while (p && !ch[p][c]) ch[p][c]=np,p=ff[p];
        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[q]=ff[np]=nq;
            while (p && ch[p][c]==q) ch[p][c]=nq,p=ff[p];
          }
        }
      }
      
      void work() {
        for (ri i=1;i<=tot;i++) ton[len[i]]++;
        for (ri i=1;i<=tot;i++) ton[i]+=ton[i-1];
        for (ri i=1;i<=tot;i++) a[ton[len[i]]--]=i;
        for (ri i=tot;i>=1;i--) cnt[ff[a[i]]]+=cnt[a[i]];
        if (t==0) {
          for (ri i=2;i<=tot;i++) cnt[i]=1;
        }
        cnt[1]=0;
        for (ri i=1;i<=tot;i++) sum[i]=cnt[i];
        for (ri i=tot;i>=1;i--)
          for (ri j=0;j<26;j++) sum[a[i]]+=sum[ch[a[i]][j]];
      }
      
      void query(int x) {
        if (les<k && k<=les+cnt[x]) {
          return;
        }
        les+=cnt[x];
        for (ri i=0;i<26;i++) {
          if (!ch[x][i]) continue;
          les+=sum[ch[x][i]];
          if (les>=k) {
            les-=sum[ch[x][i]];
            printf("%c",'a'+i);
            query(ch[x][i]);
            return;
          }
        }
      }
    } sam;
    
    int main(){
      scanf("%s",s+1); n=strlen(s+1);
      scanf("%d %d",&t,&k);
      sam.init();
      for (ri i=1;i<=n;i++) sam.extend(s[i]-'a');
      sam.work();
      if (sam.sum[1]<k) {
        puts("-1");
      }
      else {
        les=0;
        sam.query(1);
      }
    }
  • 相关阅读:
    hdu 1290 献给杭电五十周年校庆的礼物 (DP)
    hdu 3123 GCC (数学)
    hdu 1207 汉诺塔II (DP)
    hdu 1267 下沙的沙子有几粒? (DP)
    hdu 1249 三角形 (DP)
    hdu 2132 An easy problem (递推)
    hdu 2139 Calculate the formula (递推)
    hdu 1284 钱币兑换问题 (DP)
    hdu 4151 The Special Number (DP)
    hdu 1143 Tri Tiling (DP)
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279205.html
Copyright © 2011-2022 走看看