AT_arc081_c [ARC081E] Don't Be a Subsequence
题目链接
设 \(f_{i,A_i}\) 表示在 \([i,|A|]\) 以 \(A_i\) 为开头的答案最短为多少,设 \(p_j\) 为字符 \(j\) 在 \([i+1,|A|]\) 内的第一次出现地方。
\[f_{i,A_i}=1+\min{f_{p_c,c}}
\]
Code:
#include<bits/stdc++.h>
#define LL long long
//#define int LL
#define per(i, a, b) for (int i = a, END##i = b; i >= END##i; i--)
#define rep(i, a, b) for (int i = a, END##i = b; i <= END##i; i++)
#define repn(x) rep(x, 1, n)
#define repm(x) rep(x, 1, m)
#define pb push_back
#define e(x) for(int i = h[x], v = to[i]; i; i = nxt[i], v = to[i])
#define E(x) for(auto y : p[x])
#define PII pair<int, int>
#define i64 unsigned long long
#define YY puts("Yes"), exit(0)
#define NN puts("No"), exit(0)
using namespace std;
const int Mod = 1e9 + 7;
const int Inf = 0x3f3f3f3f;
const LL InfLL = 0x3f3f3f3f3f3f3f3f;
inline LL read() {LL s = 0, fu = 1; char ch = getchar(); while (ch < '0' || ch > '9') ch == '-' ? fu = -1 : 0, ch = getchar(); while (ch >= '0' && ch <= '9') s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * fu;}
inline void add(int &a, int b) {((a += b) >= Mod) and (a -= Mod);}
inline int Add(int a, int b) {return add(a, b), a;}
inline int mul(int a, int b) {return 1LL * a * b % Mod;}
inline void Mul(int &a, int b) {a = mul(a, b);}
inline int qpow(int a, LL b){if(!b) return 1; int c = qpow(a, b >> 1LL); Mul(c, c); if(b & 1) Mul(c, a); return c;}
inline int INV(int x) {return qpow(x, Mod - 2);}
const int N = 2e5 + 50; // 注意要开26个
int n, f[26], g[N], p[26];
char s[N];
inline void Main() {
scanf("%s", s + 1);
n = strlen(s + 1);
rep(c, 0, 25) s[p[c] = ++n] = 'a' + c;
per(i, n - 26, 0) {
g[i] = p[0];
rep(c, 1, 25) if (f[c] < f[s[g[i]] - 'a'])
g[i] = p[c];
if (i) {
f[s[i] - 'a'] = f[s[g[i]] - 'a'] + 1;
p[s[i] - 'a'] = i;
}
}
for (int i = g[0]; i; i = g[i])
putchar(s[i]);
puts("");
}
signed main() {
// freopen("input.in", "r", stdin);
int T = 1;
while (T--)
Main();
return 0;
}

浙公网安备 33010602011771号