CF1037H Security
Description#
给定一个文本串
Solution#
好像对
会发现这题能和 你的名字 套路极度地像。同样,先考虑询问全是
situation 1#
既然要求字典序必须要严格大于
所以对
situation 2#
如果是区间的话,发现我们好像需要
那就还是用线段树合并解决
插一嘴#
刚想着要继续说什么,但是发现这样子就已经做完了。。甚至感觉
不!
这是线段树合并维护
Code#
Code
/*
*/
#include
using namespace std;
typedef long long ll;
const int N = 4e5 + 10, M = 4e6 + 10;
int rt[N], tot, ls[M], rs[M], nxt[N];
inline int read() {
char ch = getchar();
int s = 0, w = 1;
while (!isdigit(ch)) {if (ch == '-') w = -1; ch = getchar();}
while (isdigit(ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar();}
return s * w;
}
inline void modify(int &now, int lt, int rt, int it) {
if (!now) now = ++tot;
if (lt == rt) return ;
int mid = (lt + rt) >> 1;
if (it <= mid) modify(ls[now], lt, mid, it);
else modify(rs[now], mid + 1, rt, it);
}
inline bool query(int now, int lt, int rt, int L, int R) {
if (!now) return 0;
if (L <= lt && rt <= R) return 1;
int mid = (lt + rt) >> 1, res = 0, ret = 0;
if (L <= mid) res = query(ls[now], lt, mid, L, R);
if (R > mid) ret = query(rs[now], mid + 1, rt, L, R);
return res | ret;
}
inline int merge(int u, int v, int lt, int rt) {
if (!u) return v;
if (!v) return u;
if (lt == rt) return u | v;
int mid = (lt + rt) >> 1, w = ++tot;
ls[w] = merge(ls[u], ls[v], lt, mid);
rs[w] = merge(rs[u], rs[v], mid + 1, rt);
return w;
}
struct SAM {
int n, cnt, las, len[N], link[N], ch[N][26];
char s[N]; int tong[N], rk[N], mx[N];
inline void init() {
cnt = las = 1;
memset(ch[1], 0, sizeof(ch[1]));
}
inline void SAM_stru(int c) {
int cur = ++cnt, p = las;
memset(ch[cur], 0, sizeof(ch[cur]));
las = cur;
len[cur] = len[p] + 1;
while (p && !ch[p][c]) ch[p][c] = cur, p = link[p];
if (!p) {link[cur] = 1; return ;}
int q = ch[p][c];
if (len[p] + 1 == len[q]) {link[cur] = q; return ;}
int clo = ++cnt;
link[clo] = link[q]; len[clo] = len[p] + 1;
link[q] = link[cur] = clo;
memcpy(ch[clo], ch[q], sizeof(ch[clo]));
while (p && ch[p][c] == q) ch[p][c] = clo, p = link[p];
}
inline void Tong_sort() {
for (int i = 1; i <= cnt; ++i) ++tong[len[i]];
for (int i = 1; i <= cnt; ++i) tong[i] += tong[i - 1];
for (int i = 1; i <= cnt; ++i) rk[tong[len[i]]--] = i;
for (int i = cnt, v, u; i >= 1; --i) {
v = rk[i]; u = link[v];
rt[u] = merge(rt[u], rt[v], 0, n - 1);
}
}
} s, t;
inline void mian() {
int l = read() - 1, r = read() - 1;
scanf("%s", t.s); t.n = strlen(t.s);
int v = 1, it = 0;
for (int i = 0, c; i <= t.n; ++i, it = i) {
nxt[i] = -1;
c = t.s[i] - 'a';
for (int j = max(c + 1, 0), u; j < 26; ++j) {
u = s.ch[v][j];
if (u && query(rt[u], 0, s.n - 1, l + i, r)) {
nxt[i] = j; break;
}
}
if (i == t.n || !s.ch[v][c] || !query(rt[s.ch[v][c]], 0, s.n - 1, l + i, r)) break;
v = s.ch[v][c];
}
while (~it && nxt[it] == -1) --it;
if (it == -1) return printf("-1\n"), void();
for (int i = 0; i < it; ++i) cout << t.s[i];
cout << (char)(nxt[it] + 'a') << "\n";
}
int main() {
scanf("%s", s.s); s.n = strlen(s.s); s.init();
for (int i = 0; i < s.n; ++i) {
s.SAM_stru(s.s[i] - 'a');
modify(rt[s.las], 0, s.n - 1, i);
}
s.Tong_sort();
int T = read();
while (T--) mian();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端