[spoj7258]Lexicographical Substring Search && 后缀自动机

本文深入探讨了后端开发领域的关键技术和算法应用,包括PHP、Python、Java等编程语言,以及排序算法、动态规划等核心算法。通过实例分析,展示了如何在实际项目中高效实现后端逻辑和优化解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

建立完后缀自动机过后用f[i]表示节点i以及i的儿子缩代表的串的个数

排序过后由深的点往浅的点更新

询问的时候进去跑一跑就好

SPOJ时间限制真是紧

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
#define idx(c) (c-'a')
using namespace std;
typedef long long LL;
const int MAXN = 180000;
int n;
char s[MAXN+10];
struct SAM {
	int fa[MAXN+10], ch[MAXN+10][26], step[MAXN+10];
	int f[MAXN+10], last, ncnt, v[MAXN+10], sa[MAXN+10];
	void extend(int c) {
		int p = last, np = last = ++ncnt;
		n = step[np] = step[p]+1;
		while(!ch[p][c] && p) ch[p][c] = np, p = fa[p];
		if(!p) fa[np] = 1;
		else {
			int q = ch[p][c], nq;
			if(step[q] == step[p]+1) fa[np] = q;
			else {
				nq = ++ncnt;
				step[nq] = step[p]+1;
				memcpy(ch[nq], ch[q], sizeof(ch[nq]));
				fa[nq] = fa[q]; fa[np] = fa[q] = nq;
				while(ch[p][c] == q && p) ch[p][c] = nq, p = fa[p];
			}
		}
	}
	inline void build() {
		SF("%s", s);
		for(char *c = s; *c; c++) extend(*c-'a');
	} 
	inline void solve() {
		for(int i = 1; i <= ncnt; i++) v[step[i]]++;
		for(int i = 1; i <= n; i++) v[i] += v[i-1];
		for(int i = 1; i <= ncnt; i++) sa[v[step[i]]--] = i;
		for(int i = ncnt; i >= 1; i--) {
			f[sa[i]] = 1;
			for(int j = 0; j < 26; j++)
				f[sa[i]] += f[ch[sa[i]][j]];
		}
	}
	inline void query() {
		int k, u = 1;
		SF("%d", &k);
		while(k) {
			for(int c = 0; c < 26; c++) 
				if(ch[u][c]) {
					if(f[ch[u][c]] < k) k -= f[ch[u][c]];
					else {
						k--;
						putchar('a'+c);
						u = ch[u][c];
                                                break;
					}
				}
		}
		puts("");
	}
} ac;
int main() {
	ac.last = ac.ncnt = 1;
	ac.build();
	ac.solve();
	int Q; SF("%d", &Q);
	for(int i = 1; i <= Q; i++)
		ac.query();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值