社区讨论

数据范围疑惑(求调

P3038[USACO11DEC] Grass Planting G参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@loh2qrjf
此快照首次捕获于
2023/11/02 18:59
2 年前
此快照最后确认于
2023/11/02 20:41
2 年前
查看原帖
数据范围不是1e5吗, 为啥N开到2e5才能过?
CPP

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010, M = 2 * N;

struct Node
{
    int l, r;
    int add;
}tr[N];

int n, m;
int h[N], e[M], ne[M], idx;
int id[N], cnt;
int top[N], fa[N], dep[N], sz[N], son[N];

void add(int a, int b)
{
	e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

void dfs1(int u, int p, int depth)
{
	fa[u] = p, dep[u] = depth, sz[u] = 1;
	for (int i = h[u]; ~i; i = ne[i])
	{
		int ver = e[i];
		if (ver == p) continue;
		dfs1(ver, u, depth + 1);
		sz[u] += sz[ver];
		if (sz[ver] > sz[son[u]]) son[u] = ver;
	}
}

void dfs2(int u, int t)
{
	id[u] = ++ cnt, top[u] = t;
	if (!son[u]) return ;
	dfs2(son[u], t);
	for (int i = h[u]; ~i; i = ne[i])
	{
		int ver = e[i];
		if (ver == fa[u] || ver == son[u]) continue;
		dfs2(ver, ver);
	}
}

void pushdown(int u)
{
    if (tr[u].l != tr[u].r)
    {
        tr[u << 1].add += tr[u].add;
        tr[u << 1 | 1].add += tr[u].add;
        tr[u].add = 0;
    }
}

void build(int u, int l, int r)
{
    tr[u] = {l, r};
    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)
{
    if (tr[u].l >= l && tr[u].r <= r) tr[u].add ++ ;
    else
    {
        // pushdown(u);
        int mid = tr[u].l + tr[u].r >> 1;
        if (l <= mid) update(u << 1, l, r);
        if (r > mid) update(u << 1 | 1, l, r);
    }
}

int query(int u, int x)
{
    if (tr[u].l == x && tr[u].r == x) return tr[u].add;
    pushdown(u);
    int mid = tr[u].l + tr[u].r >> 1;
    if (x <= mid) return query(u << 1, x);
    return query(u << 1 | 1, x);
}

void update_path(int u, int v)
{
	while (top[u] != top[v])
	{
		if (dep[top[u]] < dep[top[v]]) swap(u, v);
		update(1, id[top[u]], id[u]);
		u = fa[top[u]];
	}
	if (dep[u] < dep[v]) swap(u, v);
	update(1, id[v] + 1, id[u]);
}

int main()
{
	memset(h, -1, sizeof h);
	
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n; i ++ )
	{
		int a, b;
		scanf("%d%d", &a, &b);
		add(a, b), add(b, a);
	}
	
	dfs1(1, 0, 1);
	dfs2(1, 1);
	build(1, 1, n);
	
    char op[5];
    int a, b;
	while (m -- )
	{
	    scanf("%s%d%d", op, &a, &b);
	    if (*op == 'P') update_path(a, b);
	    else if (*op == 'Q') printf("%d\n", query(1, max(id[a], id[b])));
	}
	
	return 0;
}


回复

4 条回复,欢迎继续交流。

正在加载回复...