题目大意

对于一个给定的长度为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. BZOJ 3926: [Zjoi20150]诸神眷顾的幻想乡

    3926: [Zjoi20150]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 438  Solved: 273 Descripti ...

  2. html template & import link bug

    html template & import link bug html templates is OK https://caniuse.com/#search=html%20template ...

  3. 聊聊flink的log.file配置

    本文主要研究一下flink的log.file配置 log4j.properties flink-release-1.6.2/flink-dist/src/main/flink-bin/conf/log ...

  4. [luoguP2073] 送花(set)

    传送门 set #include <set> #include <cstdio> #include <iostream> #define LL long long ...

  5. C# 通过HTTP代理访问Socket来获取邮件

    C# 通过HTTP代理访问Socket来获取邮件 关键穿透代理的代码(通过HTTP代理获取TcpClent) public class ClientHelper { public static Tcp ...

  6. linux下程序JDBC连接不到mysql数据库

    今天在linux下部署一个 JavaEE项目的时候总是连接不到Mysql数据库,检查之后发现连接池的配置确定是对的,进入linux服务器之后以mysql -uname -ppassword连接总是报A ...

  7. poj2243+poj1915骑士问题

    2243是骑士问题,八个格子的,BFS,因为要最短路经,所以没有用A*,A*跑不出来,太慢了,因为要搜索到所有解啊!一直更新最优,而BFS,一层一层搜索,第一次得到的便是最短的了!300格子,标记的话 ...

  8. mongodb按照日期分组统计

    目录 1.使用时间格式化方法 2.进行时间补偿(默认当前时区是东八区,即8x3600x1000=28800000) mongodb的默认时间是格林尼治时间,如果是要按照日期进行分组需要注意!!!. 解 ...

  9. Oracle计算时间差

    Oracle计算时间差表达式 --获取两时间的相差豪秒数 select ceil((To_date('2008-05-02 00:00:00' , 'yyyy-mm-dd hh24-mi-ss') - ...

  10. android POI搜索,附近搜索,周边搜索定位介绍

    POI搜索有三种方式.依据范围和检索词发起范围检索poiSearchInbounds.城市poi检索poiSearchInCity,周边检索poiSearchNearBy. 下以周边检索为例介绍怎样进 ...