sub1+2都是wa,sub3一片re+wa一个,sub4后面几个点过了,前6个点是re。 代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
// const int N = 11;
int t, n;
long long anss, ans[N];
int dfn[N], low[N], tot;
int stk[N], instk[N], top;
int cnt, scc[N], siz[N], sum[N];
vector<vector<int> > e(N), nw(N);
void tarjan(int u) {
dfn[u] = low[u] = ++tot;
stk[++top] = u, instk[u] = 1;
for (int v : e[u]) {
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (instk[v]) {
low[u] = min(low[u], dfn[v]);
}
}
if (dfn[u] == low[u]) {
++cnt;
int v;
do {
v = stk[top--];
instk[v] = 0;
scc[v] = cnt;
siz[cnt]++, sum[cnt]++;
} while (u != v);
}
}
void process() {
for (int u = 1; u <= n; u++) {
for (int v : e[u]) {
if (scc[u] == scc[v])
continue;
nw[scc[u]].push_back(scc[v]);
}
}
for (int i = cnt; i; i--) {
bool flag = 1;
for (int j : nw[i]) {
flag = 0;
ans[j] += ans[i] + 1LL * sum[i] * siz[j];
sum[j] += sum[i];
}
if (flag)
anss += ans[i];
}
}
int main() {
cin >> t;
while (t--) {
cin >> n;
memset(ans, 0, 8 * n);
memset(dfn, 0, 4 * n);
memset(low, 0, 4 * n);
memset(scc, 0, 4 * n);
memset(siz, 0, 4 * n);
memset(sum, 0, 4 * n);
memset(instk, 0, 4 * n);
memset(stk, 0, 4 * n);
e.clear(), nw.clear();
e.resize(n), nw.resize(n);
tot = top = cnt = anss = 0;
for (int i = 1; i < n; i++) {
char chr = getchar();
if (chr == ' ' || chr == '\n')
chr = getchar();
if (chr == '<') {
e[i].push_back(i + 1);
} else if (chr == '>') {
e[i + 1].push_back(i);
} else {
e[i].push_back(i + 1);
e[i + 1].push_back(i);
}
}
for (int i = 1; i <= n; i++) {
if (!dfn[i])
tarjan(i);
}
process();
cout << anss << '\n';
}
return 0;
}