zoukankan      html  css  js  c++  java
  • Luogu P3975 [TJOI2015]弦论

    本质不同的第 (k) 小:每个点的初始权值为 (1)

    只区分位置的第 (k) 小:每个点的初始权值为 (|{ m endpos}|) ,表示出现的次数。

    然后进行拓扑排序。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
      register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
      do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
    } const int N=1000010;
    int n,t,k,lst=1,tot=1,cnt;
    int len[N],fa[N],c[N][26],sz[N],d[N],mem[N],f[N];
    char s[N>>1];
    int vr[N<<1],nxt[N<<1],fir[N];
    inline void add(int u,int v) 
      {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;}
    inline void add(int ch) {
      R p=lst,np=lst=++tot;
      sz[tot]=1;
      len[np]=len[p]+1;
      for(;p&&!c[p][ch];p=fa[p]) c[p][ch]=np;
      if(!p) fa[np]=1;
      else {
        R q=c[p][ch];
        if(len[q]==len[p]+1) fa[np]=q;
        else {
          R nq=++tot;
          memcpy(c[nq],c[q],26<<2);
          fa[nq]=fa[q],len[nq]=len[p]+1;
          fa[np]=fa[q]=nq;
          for(;p&&c[p][ch]==q;p=fa[p]) c[p][ch]=nq;
        }
      }
    }
    inline void solve() {
      R p=1;
      while(k) {
        for(R i=0;i<26;++i) if(c[p][i]) {
          if(k>f[c[p][i]]) k-=f[c[p][i]];
          else {
            putchar(i+'a');
            p=c[p][i];
            k-=sz[p]; break;
          }
        }
      } putchar(10);
    }
    inline void main() {
      scanf("%s",s+1);
      t=g(),k=g(),n=strlen(s+1);
      for(R i=1;i<=n;++i) add(s[i]-'a');
      for(R i=1;i<=tot;++i) ++d[len[i]];
      for(R i=1;i<=n;++i) d[i]+=d[i-1];
      for(R i=1;i<=tot;++i) mem[d[len[i]]--]=i;
      if(!t) for(R i=1;i<=tot;++i) sz[i]=1;
      else for(R i=tot;i;--i) 
        sz[fa[mem[i]]]+=sz[mem[i]];;
      //sz[u]是
      //t==0: 1,表示每个点初始有个空串。
      //t==1: parent树的子树和,即 |endpos|
      //f[u]是
      //t==0: 子串个数
      //t==1: sum 每个串的出现次数(相当于是带权的)
      sz[1]=0;
      for(R i=tot;i;--i) {
        R u=mem[i];
        f[u]=sz[u];
        for(R j=0;j<26;++j) if(c[u][j])
          f[u]+=f[c[u][j]];
      } 
      if(k>f[1]) puts("-1");
      else solve();
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2020.01.09

  • 相关阅读:
    nohub
    swoole聊天室
    swoole httpserver学习
    swore tcp服务学习
    ps查看命令
    nginx和php-fpm调用方式
    Unix/Linux环境C编程入门教程(1) Solaris 11 64bit环境搭建
    Unix/Linux环境C编程入门教程(1) Solaris 11 64bit环境搭建
    C语言入门(4)——常量、变量与赋值
    C语言入门(3)——对Hello World程序的解释
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12177421.html
Copyright © 2011-2022 走看看