洛谷_3975 [TJOI2015]弦论(后缀自动机)
[TJOI2015]弦论
题目链接:https://www.luogu.com.cn/problem/P3975
题解:
对于T==0,只需要构造自动机,将每个状态节点的cnt设为1,然后DFS即可。
对于T==1,则需要额外求出每个点出现的次数,即cnt=出现次数。若状态节点不是克隆节点,则初始设cnt=1,否则cnt=0。然后按节点len降序访问每个节点,cnt[st[i].link]+=cnt[i]cnt[st[i].link] += cnt[i]cnt[st[i].link]+=cnt[i]。然后在DFS。
每个状态节点后不同字符串的数量后,在DFS求出目标串即可。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-6using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 600100;
const int mod = 998474321;
struct node{int len, link, cnt, nex[26];
}st[maxn*2];
int cnt, last, op, vis[maxn*2], tmp[2*maxn], rk[2*maxn];
LL k, ans[maxn*2];
char str[maxn], str2[maxn];
void sam(int ch);
void init();
void QSORT(int tot);
void dfs(int u);
void solve(int u, int step, LL k);int main()
{int n, i, j, m, l, r;init();scanf("%s", str);for(i=0;str[i];i++)sam(str[i]-'a');scanf("%d %lld", &op, &k);if(op == 0)for(i=0;i<cnt;i++)st[i].cnt = 1;else {QSORT(cnt);for(i=0;i<cnt;i++){int id = rk[i];if(st[id].link != -1)st[st[id].link].cnt += st[id].cnt;}}st[0].cnt = 0;dfs(0);if(k>ans[0])printf("-1\n");else{solve(0, 0, k);printf("%s\n", str2);}return 0;
}void init()
{st[0].len = 0;st[0].link = -1;st[0].cnt = 0;memset(st[0].nex, -1, sizeof(st[0].nex));last = 0, cnt = 1;
}void sam(int ch)
{int cur = cnt++, p, q;st[cur].len = st[last].len+1;st[cur].cnt = 1;memset(st[cur].nex, -1, sizeof(st[cur].nex));for(p=last;p!=-1 && st[p].nex[ch]==-1;p=st[p].link)st[p].nex[ch] = cur;if(p == -1)st[cur].link = 0;else{q = st[p].nex[ch];if(st[p].len+1 == st[q].len)st[cur].link = q;else{int clo = cnt++;st[clo] = st[q];st[clo].len = st[p].len+1;st[clo].cnt = 0;for(;p!=-1 && st[p].nex[ch] == q;p=st[p].link)st[p].nex[ch] = clo;st[cur].link = st[q].link = clo;}}last = cur;
}void QSORT(int tot)
{for(int i=0;i<=tot;i++)tmp[i] = 0;for(int i=0;i<tot;i++)tmp[st[i].len]++;for(int i=1;i<=tot;i++)tmp[i] += tmp[i-1];for(int i=0;i<tot;i++)rk[tot-(tmp[st[i].len]--)] = i;
}void dfs(int u)
{vis[u] = 1;ans[u] = st[u].cnt;for(int i=0;i<26;i++)if(st[u].nex[i]!=-1){if(!vis[st[u].nex[i]])dfs(st[u].nex[i]);ans[u] += ans[st[u].nex[i]];}
}void solve(int u, int step, LL k)
{if(st[u].cnt>=k){str2[step] = 0;return;}k -= st[u].cnt;for(int i=0;i<26;i++)if(st[u].nex[i]!=-1){if(ans[st[u].nex[i]]>=k){str2[step] = i+'a';solve(st[u].nex[i], step+1, k);break;}else k -= ans[st[u].nex[i]];}
}
洛谷_3975 [TJOI2015]弦论(后缀自动机)相关推荐
- 洛谷 - P3975 [TJOI2015]弦论(后缀自动机)
题目链接:点击查看 题目大意:给出一个字符串 s,再给出一次询问,询问分为两种类型: 0 k:如果不同位置的相同子串算作一个,求第 k 小的子串 1 k:如果不同位置的相同子串算作多个,求第 k 小的 ...
- bzoj3998/洛谷3975 [TJOI2015]弦论 (后缀自动机)
bzoj3998/洛谷3975 [TJOI2015]弦论 题意:求第 k 小字串 方法:先建立SAM,和上一题一样按照拓扑序求出size(表示这个串出现的次数).这道题我们需要求第 k 小,所以我们还 ...
- 洛谷 [P3975 [TJOI2015]弦论
洛谷 P3975 [TJOI2015]弦论 题目描述 给定一个长度为 nnn 的字符串,求它的第 kkk 小字串:给定 ttt, ttt 为 000 则表示不同位置的相同子串算作一个,ttt 为 11 ...
- 洛谷 P3975 [TJOI2015]弦论 解题报告
P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...
- 洛谷P3975 - [TJOI2015]弦论
Portal Description 给出一个小写字母串\(s(|s|\leq5\times10^5),t\in\{0,1\},k(k\leq10^9)\),求\(s\)的第\(k\)小子串.\(t= ...
- 【题解】P3975 [TJOI2015]弦论 后缀自动机
给定一个长度为n(5e5)的字符串,求它字典序第k小的子串. 输入还有一个t,t=0时表示不同位置的相同子串算作一个,t=1表示不同位置的相同子串算作多个. 使用后缀自动机. 后缀自动机中的每条路径对 ...
- [TJOI2015]弦论 后缀自动机
字典序第 k 大 沿着自动机的边走即可,比较水的一道题吧. Code: #include <cstdio> #include <algorithm> #include < ...
- 洛谷 P4218 [CTSC2010]珠宝商 后缀自动机+点分治
题目: https://www.luogu.org/problemnew/show/P4218 分析: 一种显然的暴力就是枚举一个起点,在这个点进行dfs,然后在后缀自动机上跟着跳.跳到的点的righ ...
- 洛谷P3975 [TJOI2015]弦论
链接 点击跳转 题解 后缀自动机上每条路径都是一个子串 对于t=0t=0t=0,实际上是统计字典序第kkk小的子串,自下向上进行一个dpdpdp就可以解决这个问题 对于t=1t=1t=1,每条路径都被 ...
最新文章
- 局部响应归一化LRN(Local Response Normalization)
- proto buffer
- c语言循环结构程序设计视频,第13讲:循环结构程序设计1
- python中json模块博客园_python的json模块
- 各种数据结构性能的比较
- 屌丝创业从理性“认识你自己”开始
- 使用MyEclipse建立working set
- 三角形垂点坐标js算法(三点定圆求圆心)
- html 绝对位置居中,如何在div中对绝对定位元素进行居中?
- using + .net 中的别名
- 本地html导入印象笔记,LocalNote,让你像使用本地文件一样使用印象笔记(支持 markdown 格式)...
- 作为项目经理如何做好项目进度管理
- vm15 安装win11 预览版
- [计算流体力学][Ansys Fluent] 使用 Fluent 计算方腔热对流和卡门涡街
- 有赞.测试团队介绍(转)
- STM32驱动直流电机
- 蔡徐坤鼓励师,你安装了吗?
- 制作windows xp开机画面并替换
- 查询数据库的表(字段)名和对应的注释
- 国际海运拼箱LCL与整箱FCL有什么不同?