QOJ.ac
QOJ
ID | Submission ID | Problem | Hacker | Owner | Result | Submit time | Judge time |
---|---|---|---|---|---|---|---|
#981 | #640061 | #9406. Triangle | ucup-team004 | ucup-team004 | Failed. | 2024-10-14 03:09:18 | 2024-10-14 03:09:18 |
Details
Extra Test:
Accepted
time: 707ms
memory: 34124kb
input:
3 60000 aaaa yzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz...
output:
0 0 0
result:
ok 3 lines
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#640061 | #9406. Triangle | ucup-team004 | TL | 229ms | 42352kb | C++23 | 6.2kb | 2024-10-14 02:49:00 | 2024-10-14 03:17:24 |
answer
#include <bits/stdc++.h>
using i64 = long long;
using u64 = unsigned long long;
using u32 = unsigned;
struct SuffixArray {
int n;
std::vector<int> sa, rk, lc;
SuffixArray(const std::vector<int> &s) {
n = s.size();
sa.resize(n);
lc.resize(n - 1);
rk.resize(n);
std::iota(sa.begin(), sa.end(), 0);
std::sort(sa.begin(), sa.end(),
[&](int a, int b) {
return s[a] < s[b];
});
rk[sa[0]] = 0;
for (int i = 1; i < n; i++) {
rk[sa[i]] = rk[sa[i - 1]] + (s[sa[i]] != s[sa[i - 1]]);
}
int k = 1;
std::vector<int> tmp, cnt(n);
tmp.reserve(n);
while (rk[sa[n - 1]] < n - 1) {
tmp.clear();
for (int i = 0; i < k; i++) {
tmp.push_back(n - k + i);
}
for (auto i : sa) {
if (i >= k) {
tmp.push_back(i - k);
}
}
std::fill(cnt.begin(), cnt.end(), 0);
for (int i = 0; i < n; i++) {
cnt[rk[i]]++;
}
for (int i = 1; i < n; i++) {
cnt[i] += cnt[i - 1];
}
for (int i = n - 1; i >= 0; i--) {
sa[--cnt[rk[tmp[i]]]] = tmp[i];
}
std::swap(rk, tmp);
rk[sa[0]] = 0;
for (int i = 1; i < n; i++) {
rk[sa[i]] = rk[sa[i - 1]] + (tmp[sa[i - 1]] < tmp[sa[i]] || sa[i - 1] + k == n || tmp[sa[i - 1] + k] < tmp[sa[i] + k]);
}
k *= 2;
}
for (int i = 0, j = 0; i < n; i++) {
if (rk[i] == 0) {
j = 0;
} else {
for (j -= (j > 0); i + j < n && sa[rk[i] - 1] + j < n && s[i + j] == s[sa[rk[i] - 1] + j]; j++)
;
lc[rk[i] - 1] = j;
}
}
}
};
constexpr int N = 1E6 + 2;
int trie[N][26];
int tot;
int num;
int id[N];
int newNode() {
int x = ++tot;
std::fill(trie[x], trie[x] + 26, 0);
id[x] = -1;
return x;
}
int add(const std::string &s) {
int p = 1;
for (auto c : s) {
int i = c - 'a';
int &q = trie[p][i];
if (!q) {
q = newNode();
}
p = q;
}
if (id[p] == -1) {
id[p] = num++;
}
return id[p];
}
template <typename T>
struct Fenwick {
int n;
std::vector<T> a;
Fenwick(int n_ = 0) {
init(n_);
}
void init(int n_) {
n = n_;
a.assign(n, T{});
}
void add(int x, const T &v) {
for (int i = x + 1; i <= n; i += i & -i) {
a[i - 1] = a[i - 1] + v;
}
}
T sum(int x) {
T ans{};
for (int i = x; i > 0; i -= i & -i) {
ans = ans + a[i - 1];
}
return ans;
}
T rangeSum(int l, int r) {
return sum(r) - sum(l);
}
int select(const T &k) {
int x = 0;
T cur{};
for (int i = 1 << std::__lg(n); i; i /= 2) {
if (x + i <= n && cur + a[x + i - 1] <= k) {
x += i;
cur = cur + a[x - 1];
}
}
return x;
}
};
void solve() {
int n;
std::cin >> n;
tot = 0;
num = 0;
newNode();
std::vector<std::string> s;
std::vector<int> st;
std::vector<int> cnt;
std::vector<int> T;
for (int i = 0; i < n; i++) {
std::string a;
std::cin >> a;
int p = add(a);
if (p >= s.size()) {
st.push_back(T.size());
for (auto c : a) {
T.push_back(c);
}
T.push_back(-N + a.size());
s.push_back(a);
cnt.push_back(1);
} else {
cnt[p]++;
}
}
n = s.size();
std::vector<int> ord(n);
std::iota(ord.begin(), ord.end(), 0);
std::sort(ord.begin(), ord.end(),
[&](int i, int j) {
return s[i] + s[j] < s[j] + s[i];
});
std::vector<int> w(n);
for (int i = 0; i < n; i++) {
w[ord[i]] = i;
}
SuffixArray sa(T);
i64 ans = 0;
std::vector<std::array<i64, 4>> qry;
for (int x = 0; x < n; x++) {
int p = 1;
for (int j = 0; j < s[x].size(); j++) {
int c = s[x][j] - 'a';
p = trie[p][c];
if (!p) {
break;
}
if (id[p] != -1) {
int y = id[p];
int u = w[y];
int l = sa.rk[st[x] + j + 1];
int r = sa.rk[st[x]];
if (l > r) {
continue;
}
if (y != x) {
qry.push_back({u, l, r, 1LL * cnt[x] * cnt[y]});
if (l < sa.rk[st[y]] && sa.rk[st[y]] < r) {
ans += 1LL * cnt[x] * cnt[y] * (cnt[y] - 1) / 2;
}
if (w[x] < u && l < sa.rk[st[x]]) {
ans += 1LL * cnt[x] * (cnt[x] - 1) / 2 * cnt[y];
}
} else {
qry.push_back({u, l, r, 1LL * cnt[x] * (cnt[x] - 1) / 2});
ans += 1LL * cnt[x] * (cnt[x] - 1) * (cnt[x] - 2) / 6;
}
}
}
}
std::vector<int> p(n);
std::iota(p.begin(), p.end(), 0);
std::sort(p.begin(), p.end(),
[&](int i, int j) {
return w[i] < w[j];
});
std::sort(qry.begin(), qry.end());
Fenwick<int> fen(T.size());
for (int i = 0; auto [u, l, r, v] : qry) {
while (i < n && w[p[i]] < u) {
int j = p[i];
fen.add(sa.rk[st[j]], cnt[j]);
i++;
}
ans += v * fen.rangeSum(l + 1, r);
}
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}