G
#include<bits/stdc++.h>
#include <ostream>
using namespace std;
typedef long long ll;
#define endl '\n'
typedef pair<int, int> PII;
#define debug() cout.flush()
#define for0(i, a) for (int i = 0; i < a; ++i)
#define REP(i, a, b) for (int i = a; i < b; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REPC(i, a, b, c) for (ll i = a; i < b && i < c; ++i)
#define RREP(i, a, b) for (int i = a; i >= b; --i)
const ll MOD = 1e9 + 7;
const ll mod = 998244353;
const int INF = 0x3f3f3f3f;
const int MAXN = 3e5 + 5e3;
inline void init() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
ll n, m, q;
int op[MAXN];
vector<int>v[4050];
string s;
int ans;
inline int dfs(int x) {
int res = op[x];
int len = v[x].size();
for (int i = 0; i < len; i++) { //记录整个数的权值
res += dfs(v[x][i]);
}
if (!res) ans++; //为0表示黑白相等
return res;
}
inline void solve() {
cin >> n;
for (int i = 0; i <= n; i++) v[i].clear();
for (int i = 2; i <= n; i++) {
int pos;
cin >> pos;
v[pos].push_back(i); //建树
}
cin >> s;
for (int i = 0; i < n; i++) {
op[i + 1] = (s[i] == 'W' ? 1 : -1); //赋初值
}
ans = 0;
dfs(1);
cout << ans << endl;
}
signed main() {
init();
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
H
维护当前点后面有多少个小于等于当前点的值(记录每个值的点的个数,然后用线段树维护前缀和,每次经过点后将点删除)
#include<bits/stdc++.h>
#include <ostream>
using namespace std;
typedef long long ll;
#define endl '\n'
typedef pair<int, int> PII;
#define debug() cout.flush()
#define for0(i, a) for (int i = 0; i < a; ++i)
#define REP(i, a, b) for (int i = a; i < b; ++i)
#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define REPC(i, a, b, c) for (ll i = a; i < b && i < c; ++i)
#define RREP(i, a, b) for (int i = a; i >= b; --i)
const ll MOD = 1e9 + 7;
const ll mod = 998244353;
const int INF = 0x3f3f3f3f;
const int MAXN = 3e5 + 5e3;
inline void init() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
}
ll n, m, q;
ll sum[MAXN << 2], num[MAXN], a[MAXN];
inline void pushup(int x) {
sum[x] = sum[x << 1] + sum[x << 1 | 1];
}
inline void build(int l = 1, int r = n, int x = 1) {
if (l == r) {
sum[x] = num[l];
return;
}
int mid = l + r >> 1;
build(l, mid, x << 1);
build(mid + 1, r , x << 1 | 1);
pushup(x);
}
inline void update(int l, int r, int x, int qx) {
if (l == r) {
sum[x]--;
return;
}
int mid = l + r >> 1;
if (qx <= mid) update(l, mid, x << 1, qx);
else update(mid + 1, r, x << 1 | 1, qx);
pushup(x);
}
inline ll query(int l, int r, int x, int ql, int qr) {
if (l >= ql && r <= qr) {
return sum[x];
}
int mid = l + r >> 1;
ll res = 0;
if (ql <= mid) res += query(l, mid, x << 1, ql, qr);
if (qr > mid) res += query(mid + 1, r, x << 1 | 1, ql, qr);
return res;
}
inline void solve() {
cin >> n;
for0 (i, n + 1) num[i] = 0;
for0 (i, n) cin >> a[i], num[a[i]]++;
ll res = 0;
build();
for0 (i, n) {
update(1, n, 1, a[i]);
res += query(1, n, 1, 1, a[i]);
}
cout << res << endl;
}
signed main() {
init();
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}