Marked Ancestor - Aizu 2170 - Virtual Judge
根据题意,我们只需要得到查询节点前面那个标记的节点然后算出所有查询节点前面标记节点的和,就可以通过对标记时间的记录进行离线操作,即若标记时间大于查询时间,那么就相当于这个节点还没有被标记,那么就往前查,并且根节点1是从始至终都是根而且一开始就标记了,要特别注意一下
AC代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize("Ofast") #include <iostream> #include <queue> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <map> #include <vector> #include <set> #include <stack> #include <numeric> #include <iomanip> #define lowbit(x) ((x) & -(x)) using namespace std; const int INF = 0x3f3f3f3f; const int mod = 998244353; int pre[100010], mark[100010]; pair<int, int> Q[100010]; int get(int x, int y) { if (mark[x] < y) { return x; } else { int tmp = get(pre[x], y); pre[x] = tmp; return tmp; } } void solve() { int n, m; while (cin >> n >> m) { if (n == 0 && m == 0) { break; } for (int i = 2; i <= n; i++) { pre[i] = -1; mark[i] = INF; } mark[1] = 0; char op[2]; long long ans = 0; int cnt = 0; for (int i = 2; i <= n; i++) { cin >> pre[i]; } for (int i = 1; i <= m; i++) { int x; cin >> op >> x; if (op[0] == 'M') { mark[x] = min(i, mark[x]); } else { Q[++cnt] = pair<int, int>(x, i); } } for (; cnt > 0; cnt--) { ans += get(Q[cnt].first, Q[cnt].second); } cout << ans << endl; } return; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int _t = 1; //cin >> _t; while (_t--) { solve(); } return 0; }
Marked Ancestor(并查集好题,路径压缩)
最新推荐文章于 2024-07-13 21:27:21 发布