P8844 [传智杯 #4 初赛] 小卡与落叶
先考虑暴力做法。
对于深度
但是显然深度为
但是我们仔细分析可得,操作一里有这么一句话:把整棵树都染绿。
显然每次操作和之前的操作和查询是无关的,对每次查询产生贡献的只有上一次修改操作,并且一次修改至下一次修改之间的所有查询都可以打乱顺序,因为查询不会影响树的数据。
考虑操作离线,对于每个查询操作找到上次的修改,然后将
由于一棵树最多只有
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <utility>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
int n, m;
class SegmentTree
{
public:
struct Node
{
int l, r, sum;
int tag;
}tr[N << 2];
void pushup(int u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void pushdown(int u)
{
if (tr[u].tag != -1)
{
tr[u << 1].tag = tr[u].tag;
tr[u << 1].sum = tr[u].tag * (tr[u << 1].r - tr[u << 1].l + 1);
tr[u << 1 | 1].tag = tr[u].tag;
tr[u << 1 | 1].sum = tr[u].tag * (tr[u << 1 | 1].r - tr[u << 1 | 1].l + 1);
tr[u].tag = -1;
}
}
void build(int u, int l, int r)
{
tr[u] = { l, r, 0, -1 };
if (l == r) return;
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
}
void update(int u, int l, int r, int c)
{
if (tr[u].l >= l and tr[u].r <= r)
{
tr[u].tag = c;
tr[u].sum = c * (tr[u].r - tr[u].l + 1);
}
else
{
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) update(u << 1, l, r, c);
if (r > mid) update(u << 1 | 1, l, r, c);
pushup(u);
}
}
int query(int u, int l, int r)
{
if (tr[u].l >= l and tr[u].r <= r)
{
return tr[u].sum;
}
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1, sum = 0;
if (l <= mid) sum = query(u << 1, l, r);
if (r > mid) sum += query(u << 1 | 1, l, r);
return sum;
}
}f;
vector<int> G[N];
vector<pair<int, int> > p[N];
vector<int> DEP[N];
int sz[N], dep[N], ans[N], idx;
int id[N], idx2;
void dfs(int u, int fa)
{
dep[u] = dep[fa] + 1;
DEP[dep[u]].push_back(u);
sz[u] = 1;
id[u] = ++idx2;
for (int i = 0; i < G[u].size(); i++)
{
int j = G[u][i];
if (j != fa)
{
dfs(j, u);
sz[u] += sz[j];
}
}
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
int last = 0;
for (int i = 1; i <= m; i++)
{
int op, x;
scanf("%d%d", &op, &x);
if (op == 1)
{
last = x;
}
else
{
p[last].push_back(make_pair(x, ++idx));
}
}
dfs(1, 0);
f.build(1, 1, n);
for (int i = 0; i <= n; i++)
{
if (p[i].size() == 0) continue;
if (i == 0)
{
for (pair<int, int> j : p[i])
{
ans[j.second] = 0;
}
}
else
{
f.update(1, 1, n, 0);
for (int j : DEP[i])
{
//printf("%d %d\n", i, j);
f.update(1, id[j], id[j] + sz[j] - 1, 1);
}
for (pair<int, int> j : p[i])
{
ans[j.second] = f.query(1, id[j.first], id[j.first] + sz[j.first] - 1);
}
}
}
for (int i = 1; i <= idx; i++)
{
printf("%d\n", ans[i]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!