并不对劲的bzoj3998:loj2102:p3975:[TJOI2015]弦论
题目大意
对于一个给定的长度为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]弦论的更多相关文章
- Luogu P3975 [TJOI2015]弦论
题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...
- 洛谷 P3975 [TJOI2015]弦论 解题报告
P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...
- luogu P3975 [TJOI2015]弦论 SAM
luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...
- P3975 [TJOI2015]弦论
思路 一眼SAM板子,结果敲了一中午... 我还是太弱了 题目要求求第k小的子串 我们可以把t=0当成t=1的特殊情况,(所有不同位置的相同子串算作一个就是相当于把所有子串的出现位置个数(endpos ...
- [洛谷P3975][TJOI2015]弦论
题目大意:求一个字符串的第$k$大字串,$t$表示长得一样位置不同的字串是否算多个 题解:$SAM$,先求出每个位置可以到达多少个字串($Right$数组),然后在转移图上$DP$,若$t=1$,初始 ...
- 【BZOJ3998】[TJOI2015]弦论 后缀自动机
[BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...
- bzoj3998: [TJOI2015]弦论(SAM+dfs)
3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2627 Solved: 881 Description 对于一 ...
随机推荐
- Laya 分帧加载优化
Laya 分帧加载优化 @author ixenos Flash中的EnterFrame事件在Laya中等同于Laya.timer.frameLoop(1,...) Laya.timer.frameL ...
- Divide Groups(分组)(二分图染色)
题目链接 题目大意是说输入数字n 然后告诉你第i个人都认识谁? 让你把这些人分成两堆,使这每个堆里的人都互相认识. 做法:把不是互相认识的人建立一条边,则构建二分图,两堆的人肯定都互相认识,也就是说, ...
- bzoj4027 [HEOI2015]兔子与樱花 树上贪心
[HEOI2015]兔子与樱花 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1320 Solved: 762[Submit][Status][Di ...
- 【BZOJ2560】串珠子(状压DP,容斥原理)
题意: 铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子.现在铭铭想用绳子把所有的珠子连接成一个整体.现在已知所有珠子互不相同,用整数1到n编号.对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者在 ...
- BZOJ1704: [Usaco2007 Mar]Face The Right Way 自动转身机
n<=5000个数0或1,每次可以连续对固定长度区间取反,目标把所有1变0,求一个取反区间的固定长度K使取反次数最少. 答案关于K不单调,因此枚举K,对每个K扫一遍区间,遇到1就把连续K个数反转 ...
- MITM Proxy环境搭建
MITM_Proxy环境搭建 环境要求 系统环境要求: Ubuntu 14.04 x64,CentOS 7 x64以上版本系统(建议使用xubuntu 14.04 x64,稳定硬件要求低) Pytho ...
- Es首页
https://www.elastic.co/guide/en/elasticsearch/reference/index.html
- [Bzoj1083][SCOI2005]互不侵犯king(状压dp)
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4595 Solved: 2664[Submit][ ...
- POJ 3230 【DP】
题意: 某货旅行,在n个城市呆m天. 给出从第i个城市到第j个城市的路费,或者留在某个城市的生活费. 给出在第i天在第j个城市的收益. 可以在城市之间任意穿梭逗留没有其他特殊要求. 求收益最大是多少. ...
- RESTful API设计规范收集
说明:其实没有绝对的规范,达到90%即可. 理解RESTful架构:http://www.ruanyifeng.com/blog/2011/09/restful.html RESTful API 设计 ...