1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include<bits/stdc++.h>
using namespace std;
const int MAXN = 20005;
int q, v, ind = 0; string s; int cost[MAXN], val[MAXN];
int vis[MAXN]; int edgeCount; int head[MAXN], toNode[MAXN], nextEdge[MAXN]; int siz[MAXN], son[MAXN];
vector< vector<int> > f; int ans[MAXN]; vector< pair<int, int> > era;
inline void addEdge(int from, int to) { edgeCount++; toNode[edgeCount] = to; nextEdge[edgeCount] = head[from]; head[from] = edgeCount; return; }
inline int read() { int x = 0; char ch = getchar(); while (!isdigit(ch)) ch = getchar(); while (isdigit(ch)) { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x; }
inline void dfs1(int from, int father) { siz[from]++; for (int i = head[from]; i; i = nextEdge[i]) { int to = toNode[i]; if (to != father) { dfs1(to, from); siz[from] += siz[to]; if (siz[son[from]] < siz[to]) son[from] = to; } } return; } inline void dfs2(int from, int father) { for (int j = cost[from]; j <= v; ++j) f.back()[j] = max(f.back()[j], f.back()[j - cost[from]] + val[from]); ans[from] = f.back()[v]; for (int i = head[from]; i; i = nextEdge[i]) { int to = toNode[i]; if (to != father && to != son[from]) { f.push_back(f.back()); dfs2(to, from); f.pop_back(); } } if (son[from]) dfs2(son[from], from); return; }
int main() { q = read(), v = read(); f.push_back(vector<int>(v + 1, 0)); vis[0] = 20001; for (int i = 1; i <= q; ++i) { cin >> s; if (s[0] == 'a') { addEdge(vis[ind], i); vis[++ind] = i; cost[i] = read(), val[i] = read(); } else --ind, era.push_back({i, vis[ind]}); } dfs1(vis[0], 0); dfs2(vis[0], 0); for (auto i : era) ans[i.first] = ans[i.second]; for (int i = 1; i <= q; ++i) cout << ans[i] << '\n'; return 0; }
|