T1 排列鞋子
T2 P3459 POI 2007 MEG-Megalopolis
场切了,没有思维,全是码量。
还好考场上坚持调试这一题
思路
首先注意到题目中给出的是一棵树。初始每一条边权为 \(1\) ,那么修改边相当于将边权置为 \(0\)。
考虑把这棵树拍到 dfn 序上,并记录每个节点的深度。由于每一棵子树在 dfn 序列中都是连续的。所以修改和查询操作相当于区间修改和单点查询。
考虑用线段树维护深度。
代码
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 250005;
int cnt, n, m, dep[N], dfn[N], dfn2[N];
struct node
{
int l, r;
} a[N];
struct tree
{
int data, lzy;
} w[N << 2];
vector<int> g[N];
bool InRange(int l, int r, int L, int R) { return (l >= L) && (r <= R); }
bool OutofRange(int l, int r, int L, int R) { return (r < L) || (l > R); }
void pushup(int u)
{
w[u].data = w[u * 2].data + w[u * 2 + 1].data;
}
void pushdown(int u, int l, int r)
{
if (w[u].lzy == 0)
return;
w[u * 2].lzy += w[u].lzy, w[u * 2 + 1].lzy += w[u].lzy;
int mid = l + r >> 1;
w[u * 2].data -= (mid - l + 1) * w[u].lzy;
w[u * 2 + 1].data -= (r - mid) * w[u].lzy;
w[u].lzy = 0;
}
void build(int u, int l, int r)
{
if (l == r)
{
w[u].data = dep[l];
return;
}
int mid = l + r >> 1;
build(u * 2, l, mid);
build(u * 2 + 1, mid + 1, r);
pushup(u);
}
void update(int u, int l, int r, int L, int R)
{
if (InRange(l, r, L, R))
{
w[u].lzy++;
w[u].data -= r - l + 1;
return;
}
if (OutofRange(l, r, L, R))
return;
int mid = l + r >> 1;
pushdown(u, l, r);
update(u * 2, l, mid, L, R);
update(u * 2 + 1, mid + 1, r, L, R);
pushup(u);
}
int query(int u, int l, int r, int L, int R)
{
if (InRange(l, r, L, R))
return w[u].data;
if (OutofRange(l, r, L, R))
return 0;
int mid = l + r >> 1;
pushdown(u, l, r);
return query(u * 2, l, mid, L, R) + query(u * 2 + 1, mid + 1, r, L, R);
}
int dfs(int x, int fa, int sum)
{
a[x] = {++cnt, cnt};
dfn[x] = cnt;
dfn2[cnt] = x;
dep[cnt] = sum;
for (int v : g[x])
{
if (v == fa)
continue;
a[x].r = dfs(v, x, sum + 1);
}
return a[x].r;
}
signed main()
{
// freopen("meg.in", "r", stdin);
// freopen("meg.out", "w", stdout);
cin >> n;
for (int i = 1; i < n; i++)
{
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
// cin >> dep[i];
}
dfs(1, 0, 0);
build(1, 1, n);
// for (int i = 1; i <= n; i++)
// {
// cout << a[i].l << " " << a[i].r << endl;
// }
// for (int i = 1; i <= n; i++)
// {
// cout << dfn[i] << " ";
// }
// cout << endl;
// for (int i = 1; i <= n; i++)
// {
// cout << query(1, 1, n, dfn[a[i].l], dfn[a[i].l]) << " ";
// }
cin >> m;
for (int i = 1; i <= n + m - 1; i++)
{
char op;
cin >> op;
if (op == 'W')
{
int x;
cin >> x;
cout << query(1, 1, n, dfn[x], dfn[x]) << endl;
// cout << dep[dfn[x]] << endl;
}
if (op == 'A')
{
int x, y;
cin >> x >> y;
update(1, 1, n, a[y].l, a[y].r);
// for (int i = 1; i <= n; i++)
// {
// cout << query(1, 1, n, a[i].l, a[i].l) << " ";
// }
// cout << endl;
}
}
}