QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#744207 | #5084. Longest Substring | ucup-team5062# | TL | 0ms | 3768kb | C++20 | 2.6kb | 2024-11-13 21:09:59 | 2024-11-13 21:10:08 |
Judging History
answer
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
string to_string(const vector<int>& arr) {
string res = "[";
for (int i = 0; i < int(arr.size()); i++) {
if (i != 0) {
res += ", ";
}
res += to_string(arr[i]);
}
res += "]";
return res;
}
vector<int> solve(int N, const string& S) {
vector<int> A(N + 1);
for (int i = 0; i < N; i++) {
A[i] = 1 << (S[i] - 'a');
}
A[N] = 1 << 26;
int Z = 1;
vector<int> g(N + 1, 0), b(N + 1), created(N + 1), cnt(N + 1), best(N + 1), ans(N + 1);
ans[1] = N;
for (int i = 0; i < N; i++) {
// cerr << i << ": " << to_string(g) << endl;
for (int j = 0; j < Z; j++) {
b[j] = 0;
}
for (int j = 0; j <= N - i; j++) {
b[g[j]] |= A[j + i];
}
// cerr << i << ": " << to_string(g) << " " << to_string(cnt) << endl;
for (int j = 0; j < Z; j++) {
if (b[j] & (b[j] - 1)) {
if (created[j] > 0) {
int base = 0, basecur = 0;
while (basecur <= N - i) {
if (g[basecur] == j) {
basecur += created[j];
base++;
} else {
basecur++;
}
}
int l = created[j], r = i + 1;
while (r - l > 1) {
int m = (l + r) / 2;
int score = 0, cur = 0;
while (cur <= N - i) {
if (g[cur] == j) {
cur += m;
score++;
} else {
cur++;
}
}
if (score == base) {
l = m;
} else {
r = m;
}
}
if (best[cnt[j]] <= base) {
best[cnt[j]] = base;
ans[cnt[j]] = l;
}
}
cnt[j] = 0;
for (int k = 0; k < N - i; k++) {
if (g[k] == j) {
int c = __builtin_popcount(b[j] & (A[k + i] - 1));
int mark = (c ? Z + c - 1 : j);
g[k] = mark;
cnt[mark]++;
}
}
int nxtZ = Z + __builtin_popcount(b[j] & ((1 << 26) - 1)) - 1;
created[j] = i + 1;
for (int k = Z; k < nxtZ; k++) {
created[k] = i + 1;
}
Z = nxtZ;
}
}
g[N - i] = -1;
}
return ans;
}
#include <random>
mt19937_64 mt(1);
void test() {
int N = 50000;
string S;
for (int i = 0; i < N; i++) {
S += mt() % 1 + 'a';
}
vector<int> ans = solve(N, S);
int sum = 0;
for (int i = 1; i <= N; i++) {
sum += ans[i];
}
cout << sum << endl;
}
int main() {
string S;
cin >> S;
int N = S.size();
vector<int> ans = solve(N, S);
for (int i = 1; i <= N; i++) {
cout << ans[i] << (i != N ? ' ' : '\n');
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3640kb
input:
ababa
output:
5 2 1 0 0
result:
ok single line: '5 2 1 0 0'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3768kb
input:
aaaaaaaa
output:
8 7 6 5 4 3 2 1
result:
ok single line: '8 7 6 5 4 3 2 1'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3644kb
input:
a
output:
1
result:
ok single line: '1'
Test #4:
score: 0
Accepted
time: 0ms
memory: 3584kb
input:
abcdefghijklmnopqrstuvwxyz
output:
26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
result:
ok single line: '26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
Test #5:
score: -100
Time Limit Exceeded
input:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...