20260713总结

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;
        }
    }
}
相关推荐
英雄哪里出来1 年前
《哈希表》K倍区间(解题报告)
数据结构·算法·散列表·哈希表·解题报告
cjh-Java3 年前
栈-二叉树的中序遍历/easy
算法·解题报告
小白菜又菜3 年前
Leetcode 299. Bulls and Cows
算法·leetcode·解题报告
小白菜又菜3 年前
Leetcode 290. Word Pattern
算法·leetcode·解题报告
小白菜又菜3 年前
Leetcode 275. H-Index II
算法·leetcode·解题报告
小白菜又菜3 年前
Leetcode 278. First Bad Version
算法·leetcode·解题报告