• 3998: [TJOI2015]弦论


    题解:

    每个点的size值就是这个从根-它出现的次数

    如果相同只算一次就全部赋值为1就可以了

    代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define rint register ll
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--)
    using namespace std;
    const ll N=1.1e6;
    char s[N];
    ll size[N],len[N],ch[N][26],sum[N];
    ll lst=1,node=1,t[N],a[N],fa[N],T,k;
    void extend(ll c)
    {
      ll f=lst,p=++node; lst=p;
      len[p]=len[f]+1; size[p]=1;
      while (f&&!ch[f][c]) ch[f][c]=p,f=fa[f];
      if (!f) { fa[p]=1; return;};
      ll x=ch[f][c],y=++node;
      if (len[f]+1==len[x]) {fa[p]=x; node--;return;};
      len[y]=len[f]+1; fa[y]=fa[x]; fa[x]=fa[p]=y;
      memcpy(ch[y],ch[x],sizeof(ch[x]));
      while (f&&ch[f][c]==x) ch[f][c]=y,f=fa[f];
    }
    void dfs(ll x)
    {
      if (k<=size[x]) 
      {
        k=0;
        return;
      }
      k-=size[x];
      rep(i,0,25)
      {
        ll y=ch[x][i];
        if (k<=sum[y])
        {
          char cc=i+'a';
          cout<<cc;
          dfs(y);
          return;
        } else k-=sum[y];
      }
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout); 
      ios::sync_with_stdio(false);
      cin>>s;
      cin>>T>>k;
      ll l=strlen(s);
      rep(i,1,l) extend(s[i-1]-'a');
      rep(i,1,node) t[len[i]]++;
      rep(i,1,node) t[i]+=t[i-1];
      rep(i,1,node) a[t[len[i]]--]=i;
      dep(i,node,1)
      {
        ll x=a[i];
        if (T) size[fa[x]]+=size[x]; else size[x]=1; 
      }
      size[0]=size[1]=0;
      dep(i,node,1)
      {
        ll x=a[i];
        sum[x]+=size[x];
        rep(j,0,25) sum[x]+=sum[ch[x][j]];
      }
      dfs(1);
      if (k) cout<<-1<<endl;
      return 0;
    }
  • 相关阅读:
    mysql时间操作函数和存储过程
    puppet foreman
    mysql c haracter
    socket
    socket 网摘
    网络安全
    sqlite3 C接口
    spring 配置文件XSD地址
    programData
    网络安全数据包分析
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9350602.html
Copyright © 2020-2023  润新知