我是唐我是唐我是唐我是唐我是zhe_zhe
  • 板块P4116 Qtree3
  • 楼主vectorxyz
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/8/2 11:46
  • 上次更新2024/8/2 13:05:04
查看原帖
我是唐我是唐我是唐我是唐我是zhe_zhe
1114241
vectorxyz楼主2024/8/2 11:46

唐氏求助树剖,思路是白色点是编号 + NN,黑点是 ii,最后查询最小值。感觉是 SegmentTree 写炸了。。

WA 0pts

#include <bits/stdc++.h>
#define int long long
using namespace std;

struct IO{char buf[1<<20],*p1,*p2;
#define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
template<typename T>inline T read(T x){T opt=1,sum=0;char ch=gc();while(!isdigit(ch))opt=(ch=='-')?-1:1,ch=gc();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=gc();return opt*sum;}
inline void put(int x){if(x<0){x=-x;putchar('-');}if(x>9)put(x/10);putchar(x%10+48);}}io;
#define read io.read(0ll)

const int N = 1e6;
vector<int> g[N];
int w[N + 5], siz[N + 5], son[N + 5], dep[N + 5], fa[N + 5], _, top[N + 5], a[N + 5], id[N + 5];

struct Segment_Tree
{
    struct node
    {
        int l, r, minn;
    }tr[N << 2];
    void build(int u, int l, int r)
    {
        tr[u].l = l, tr[u].r = r;
        if(l == r) {
            tr[u].minn = a[l];
            return ;
        }
        int mid = (l + r) / 2;
        build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
        tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
    }
    void update(int u, int l, int r, int x, int val)
    {
        if(l == r){
            tr[u].minn += val, w[u] += val;
            return; 
        }
        int mid = (l + r) / 2;
        if(x <= mid) update(u << 1, l, mid, x, val);
        else update(u << 1 | 1, mid + 1, r, x, val);
        tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
    }
    int query(int u, int l, int r)
    {
        if(l <= tr[u].l && tr[u].r <= r)
        {
            return tr[u].minn;
        }
        int mid = (tr[u].l + tr[u].r) / 2;
        int res = LONG_LONG_MAX;
        if(l <= mid) res = min(res, query(u << 1, l, r));
        if(r >  mid) res = min(res, query(u << 1 | 1, l, r));
        return res;
    }
}seg;

void dfs1(int u, int f, int deep)
{
    dep[u] = ++deep, fa[u] = f, siz[u] = 1;
    int maxn = -1;
    for(int i = 0;i < g[u].size();i ++ ){
        int v = g[u][i];
        if(v == f) continue;
        dfs1(v, u, deep + 1);
        siz[u] += siz[v];
        if(siz[v] > maxn) {
            maxn = siz[v];
            son[u] = v;
        }
    }
}

void dfs2(int u, int topf)
{
    top[u] = topf;
    id[u] = ++_;
    a[_] = w[u];
    if(!son[u]) return ;
    dfs2(son[u], topf);
    for(int i = 0;i < g[u].size();i ++ ){
        int v = g[u][i];
        if(v == fa[u] || v == son[u]) continue;
        dfs2(v, v);
    }
}

int Query(int x, int y)
{
    int ans = LONG_LONG_MAX;
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        ans = min(ans, seg.query(1, id[top[x]], id[x]));
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    ans = min(ans, seg.query(1, id[x], id[y]));
    return ans;
}

signed main()
{
    int n = read, q = read;
    for(int i = 1;i < n;i ++ ) {
        int a = read, b =  read; g[a].push_back(b), g[b].push_back(a);
    }
    for(int i = 1;i <= n;i ++ ) w[i] = i + N;
    dfs1(1, 0, 1);
    dfs2(1, 1);
    seg.build(1, 1, n);
    while(q -- )
    {
        int op = read, v = read;
        if(op == 0){
            if(w[v] > N) seg.update(1, 1, n, id[v], -N);
            else seg.update(1, 1, n, id[v], N);
        }
        else {
            int ans = Query(1, v);
            if(ans > N || ans < 0) cout << -1 << endl;
            else cout << ans << endl;
        }
        // for(int i = 1;i <= n;i ++ ) cout << w[i] << ' ';
        // cout << endl;
    }

    return 0;
}
2024/8/2 11:46
加载中...