QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#497743 | #3836. So I'll Max Out My Constructive Algorithm Skills | PetroTarnavskyi# | WA | 0ms | 3616kb | C++20 | 3.2kb | 2024-07-29 17:05:08 | 2024-07-29 17:05:08 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second
typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;
const int INF = 1e9;
const int ALP = 26;
struct DSU
{
int n;
VI p, sz;
void init(int _n)
{
n = _n;
p.resize(n);
iota(ALL(p), 0);
sz.assign(n, 1);
}
int find(int v)
{
if (v == p[v])
return v;
return p[v] = find(p[v]);
}
bool unite(int u, int v)
{
u = find(u);
v = find(v);
if (u == v)
return false;
if (sz[u] > sz[v])
swap(u, v);
p[u] = v;
sz[v] += sz[u];
return true;
}
};
struct SuffixArray
{
int n;
VI s;
VI sa, rnk;
void init(const VI& _s)
{
n = SZ(_s);
s = _s;
sa = suffixArray();
rnk.resize(n);
FOR(i, 0, n)
rnk[sa[i]] = i;
}
void countSort(VI& p, const VI& c)
{
VI cnt(n);
FOR(i, 0, n)
cnt[c[i]]++;
VI pos(n);
FOR(i, 1, n)
pos[i] = pos[i - 1] + cnt[i - 1];
VI p2(n);
for (auto x : p)
{
int i = c[x];
p2[pos[i]++] = x;
}
p = p2;
}
VI suffixArray()
{
s.PB(-INF);
n++;
VI p(n), c(n);
iota(ALL(p), 0);
sort(ALL(p), [&](int i, int j)
{
return s[i] < s[j];
});
int x = 0;
c[p[0]] = 0;
FOR(i, 1, n)
{
if (s[p[i]] != s[p[i - 1]])
x++;
c[p[i]] = x;
}
int k = 0;
while ((1 << k) < n)
{
FOR(i, 0, n)
p[i] = (p[i] - (1 << k) + n) % n;
countSort(p, c);
VI c2(n);
PII pr = {c[p[0]], c[(p[0] + (1 << k)) % n]};
FOR(i, 1, n)
{
PII nx = {c[p[i]], c[(p[i] + (1 << k)) % n]};
c2[p[i]] = c2[p[i - 1]];
if (pr != nx)
c2[p[i]]++;
pr = nx;
}
c = c2;
k++;
}
p.erase(p.begin());
s.pop_back();
n--;
return p;
}
};
struct Lcp
{
VI lcp;
SuffixArray a;
void init(const SuffixArray& _a)
{
a = _a;
lcp = lcpArray();
}
VI lcpArray()
{
lcp.resize(a.n - 1);
int h = 0;
FOR(i, 0, a.n)
{
if (h > 0)
h--;
if (a.rnk[i] == 0)
continue;
int j = a.sa[a.rnk[i] - 1];
for (; j + h < a.n && i + h < a.n; h++)
{
if (a.s[j + h] != a.s[i + h])
break;
}
lcp[a.rnk[i] - 1] = h;
}
return lcp;
}
};
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
VI a, index;
a.reserve(4e6);
index.reserve(4e6);
FOR(i, 0, n)
{
string s;
cin >> s;
for (char c : s)
{
a.PB(c - 'a');
index.PB(i);
}
a.PB(i + ALP);
index.PB(-1);
}
SuffixArray sa;
sa.init(a);
Lcp lcp;
lcp.init(sa);
vector<tuple<int, int, int>> edges;
edges.reserve(4e6);
FOR(i, 0, SZ(lcp.lcp))
{
int u = index[sa.sa[i]], v = index[sa.sa[i + 1]];
if (u != -1 && v != -1)
edges.PB({lcp.lcp[i], u, v});
}
sort(ALL(edges), greater());
DSU dsu;
dsu.init(n);
LL ans = 0;
for (auto [w, u, v] : edges)
{
if (dsu.unite(u, v))
{
ans += w;
}
}
cout << ans << "\n";
return 0;
}
詳細信息
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 3616kb
input:
1 2 4 3 2 1
output:
0
result:
wrong answer Integer 0 violates the range [1, 4]