题目大意

对于一个给定的长度为n(\(n\leq5*10^5\))的字符串,

分别求出不同位置的相同子串算作一个、不同位置的相同子串算作多个时,它的第k(\(k\leq10^9\))小子串是什么

题解

建这个字符串的后缀自动机

先dp求出后缀自动机上每一个点能走到多少个字符串

然后从根节点出发,每次走连向dp值不超过k且尽可能大的点的边

代码
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define maxn 500001
#define maxm 1000001
#define int long long
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
int ch[maxm][26],fa[maxm],rt,lst,cnt,t,n,fir[maxm],nxt[maxm*2],v[maxm*2],cntrd,in[maxm],q[maxm],tl,hd=1,len;
int rgt[maxm],sum[maxm],K;
char s[maxn],ans[maxn];
void ade(int u1,int v1){v[cntrd]=v1,nxt[cntrd]=fir[u1],fir[u1]=cntrd++;}
int gx(char c){return c-'a';}
void ext(int i)
{
int p=lst,np=++cnt,val=gx(s[i]);sum[np]=i,lst=np,rgt[np]=1;
for(;p&&!ch[p][val];p=fa[p])ch[p][val]=np;
if(!p)fa[np]=rt;
else
{
int q=ch[p][val];
if(sum[q]==sum[p]+1)fa[np]=q;
else
{
int nq=++cnt;
sum[nq]=sum[p]+1,fa[nq]=fa[q],fa[q]=fa[np]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
for(;p&&ch[p][val]==q;p=fa[p])ch[p][val]=nq;
}
}
}
int cmp(int x,int y){return sum[x]<sum[y];}
signed main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
memset(fir,-1,sizeof(fir));
scanf("%s",s+1);lst=rt=++cnt;
t=read(),K=read(),n=strlen(s+1);
rep(i,1,n)ext(i);
rep(i,1,cnt)in[sum[i]]++;
rep(i,1,n)in[i]+=in[i-1];
rep(i,1,cnt)q[in[sum[i]]--]=i;
dwn(i,cnt,1)rgt[fa[q[i]]]+=rgt[q[i]],in[i]=0;
rep(i,1,cnt)
{
rep(j,0,25)if(ch[i][j])in[i]++,ade(ch[i][j],i);
if(in[i]==0)q[++tl]=i;sum[i]=0;
}
if(!t)rep(i,2,cnt)rgt[i]=1;
rgt[rt]=0;
while(hd<=tl)
{
int u=q[hd++];sum[u]+=rgt[u];
for(int k=fir[u];k!=-1;k=nxt[k])
{
sum[v[k]]+=sum[u],in[v[k]]--;
if(in[v[k]]==0)q[++tl]=v[k];
}
}
int u=rt;
while(u&&K>rgt[u])
{
int tmp=rgt[u];int nx=0;
rep(i,0,25)
{
int vv=ch[u][i];
if(vv&&tmp+sum[vv]>=K){ans[++len]=i+'a';nx=1,u=vv,K-=tmp;break;}
tmp+=sum[vv];
}
if(!nx){write(-1);return 0;}
}
printf("%s",ans+1);
return 0;
}

并不对劲的bzoj3998:loj2102:p3975:[TJOI2015]弦论的更多相关文章

  1. Luogu P3975 [TJOI2015]弦论

    题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...

  2. 洛谷 P3975 [TJOI2015]弦论 解题报告

    P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...

  3. luogu P3975 [TJOI2015]弦论 SAM

    luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...

  4. P3975 [TJOI2015]弦论

    思路 一眼SAM板子,结果敲了一中午... 我还是太弱了 题目要求求第k小的子串 我们可以把t=0当成t=1的特殊情况,(所有不同位置的相同子串算作一个就是相当于把所有子串的出现位置个数(endpos ...

  5. [洛谷P3975][TJOI2015]弦论

    题目大意:求一个字符串的第$k$大字串,$t$表示长得一样位置不同的字串是否算多个 题解:$SAM$,先求出每个位置可以到达多少个字串($Right$数组),然后在转移图上$DP$,若$t=1$,初始 ...

  6. 【BZOJ3998】[TJOI2015]弦论 后缀自动机

    [BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...

  7. bzoj3998: [TJOI2015]弦论(SAM+dfs)

    3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...

  8. BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2152  Solved: 716[Submit][Status] ...

  9. 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2627  Solved: 881 Description 对于一 ...

随机推荐

  1. xtu read problem training 3 A - The Child and Homework

    The Child and Homework Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on Code ...

  2. python015 Python3 函数

    Python3 函数函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...

  3. 【数学】codeforces C. Maximal GCD

    http://codeforces.com/contest/803/problem/C [题意] 给定两个数n,k(1 ≤ n, k ≤ 10^10) 要你输出k个数,满足以下条件: ①这k个数之和等 ...

  4. 【贪心+二分】codeforces C. Sagheer and Nubian Market

    http://codeforces.com/contest/812/problem/C [题意] 如何花最少的钱买最多的纪念品?首要满足纪念品尽可能多,纪念品数量一样花钱要最少,输出纪念品数量以及最少 ...

  5. ubuntu使用git时,终端不显示git分支。

    1:问题描述: 在Windows环境下习惯使用git bash操作git分支,最近学习linux环境,发现linux环境终端不显示git分支,相关现象如下:      期望效果是: 我的linux环境 ...

  6. JS变量写到HTML页面中并修改变量值(前台处理数据序号问题)

    有时候我们在前台需要对序号进行处理,我们需要将JS变量写到页面中进行显示. 第一种方式:后台处理 第二种方式:JS中定义全局变量,然后进行显示,可以书写一个JS函数对不同的需要进行不同的替换,也就可以 ...

  7. mysql查所有列名

    查询该视图  information_schema.columns  该有的都有 desc information_schema.columns; select * from information_ ...

  8. 牛客网暑期ACM多校训练营(第六场)G

    https://www.nowcoder.com/acm/contest/144/G 链接:https://www.nowcoder.com/acm/contest/144/G来源:牛客网 In Vi ...

  9. 分析Linux文件rwx属性的含义

    Linux上的文件以.开头的文件被系统视为隐藏文件,仅用ls命令是看不到他们的,而用ls -a除了显示 一般文件名外,连隐藏文件也会显示出来. ls -l(这个参数是字母L的小写,不是数字1) 这个命 ...

  10. INFO org.apache.hadoop.ipc.RPC: Server at master/192.168.200.128:9000 not available yet, Zzzzz...

    hadoop 启动时namenode和datanode可以启动,使用jps命令也可以看到进程,但是在浏览器中输入master:50070却没有显示datanode 查看datanode的log日志: ...