树剖全RE,求助!
  • 板块P4116 Qtree3
  • 楼主Dfkuaid
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/4/16 20:39
  • 上次更新2023/11/5 00:28:38
查看原帖
树剖全RE,求助!
162191
Dfkuaid楼主2021/4/16 20:39

rt

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
#define mset(l,x) memset(l,x,sizeof(l))
using namespace std;

const int N = 100010;
const int INF = 0x3fffffff;

struct Edge{
    int u,v;
    int nxt;
};
Edge e[N << 1];

struct Node{
    int l,r;
    int ls,rs;
    int col;
    int min_d,min_p;
};
Node p[N << 2];

int n,q,tot,head[N],cnt;
int d[N],f[N],size[N],son[N];
int top[N],rk[N],id[N];

inline void add(int u,int v){
    e[++ tot].u = u;
    e[tot].v = v;
    e[tot].nxt = head[u];
    head[u] = tot;
}

inline void dfs1(int x,int fa,int depth){
    d[x] = depth;f[x] = fa;size[x] = 1;
    for (int i = head[x];i;i = e[i].nxt){
        if (e[i].v == fa) continue;
        dfs1(e[i].v,x,depth + 1);
        size[x] += size[e[i].v];
        if (size[e[i].v] > size[son[x]])
          son[x] = e[i].v;
    }
}

inline void dfs2(int x,int t){
    top[x] = t;id[x] = ++ tot;rk[tot] = x;
    if (!son[x]) return;
    dfs2(son[x],t);
    for (int i = head[x];i;i = e[i].nxt){
        if (e[i].v == f[x] || e[i].v == son[x])
          continue;
        dfs2(e[i].v,e[i].v);
    }
}

inline void pushup(int k){
//    cout << "In sub:" << k << " " << p[k].l << " " << p[k].r << endl;
//    cout << "pushup:" << p[p[k].ls].min_d << " " << p[p[k].ls].min_p << " " << p[p[k].rs].min_d << " " << p[p[k].rs].min_p << endl;
    if (p[p[k].ls].min_d < p[p[k].rs].min_d){
        p[k].min_d = p[p[k].ls].min_d;
        p[k].min_p = p[p[k].ls].min_p;
    }
    else {
        p[k].min_d = p[p[k].rs].min_d;
        p[k].min_p = p[p[k].rs].min_p;
    }
//    cout << "End pushup:" << p[k].min_d << " " << p[k].min_p << endl;
}

inline void build(int k,int l,int r){
    if (l == r){
        p[k].l = p[k].r = l;
        p[k].min_d = INF;
        p[k].min_p = 0;
        p[k].col = 0;
        return;
    }
    int mid = (l + r) >> 1;
    p[k].ls = ++ cnt;
    build(p[k].ls,l,mid);
    p[k].rs = ++ cnt;
    build(p[k].rs,mid + 1,r);
    p[k].l = p[p[k].ls].l;
    p[k].r = p[p[k].rs].r;
    p[k].min_d = INF;
    p[k].min_p = 0;
}

inline void change(int k,int x){
//    cout << "ch:" << k << " " << p[k].l << " " << p[k].r << endl;
    if (p[k].l == p[k].r){
        p[k].col ^= 1;
//        cout << " col:" << p[k].col << endl;
        if (p[k].col){
//            cout << rk[p[k].l] << endl;;
            p[k].min_d = d[rk[p[k].l]];
            p[k].min_p = rk[p[k].l];
        }
        else {
            p[k].min_p = 0;
            p[k].min_d = INF;
        }
//        cout << p[k].min_d << " " << p[k].min_p << endl;
        return;
    }
    int mid = (p[k].l + p[k].r) >> 1;
    if (x <= mid)
      change(p[k].ls,x);
    else
      change(p[k].rs,x);
    pushup(k);
//    cout << " push_check:" << p[p[k].ls].min_p << " " << p[p[k].rs].min_p << endl;
//    cout << "  push:" << p[k].min_d << " " << p[k].min_p << endl;
}

inline int query(int k,int x,int y){
    if (x <= p[k].l && p[k].r <= y)
      return p[k].min_p;
    int res,mid = (p[k].l + p[k].r) >> 1;
    if (x <= mid)
      res = query(p[k].ls,x,y);
    if (y > mid){
        int gt = query(p[k].rs,x,y);
        if (d[res] > d[gt])
          res = gt;
    }
    return res;
}

inline int ask(int x){
    int res = 0;
    while (top[x] != 1){
        int gt = query(1,id[top[x]],id[x]);
        if (d[res] > d[gt])
          res = gt;
        x = f[top[x]];
    }
    int gt = query(1,id[1],id[x]);
    if (d[res] > d[gt])
      res = gt;
    return res;
}

int main(){
    scanf("%d%d",&n,&q);
    for (int i = 1;i < n;i ++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    
    dfs1(1,0,1);
    tot = 0;
    dfs2(1,1);
    build(++ cnt,1,n);
    d[0] = INF;
//    for (int i = 1;i <= n;i ++){
//        cout << i << " " << d[i] << " " << f[i] << " " << id[i] << endl;
//    }
//    for (int i = 1;i <= n;i ++)
//      cout << rk[i] << " ";
//    cout << endl; 
//    cout << "[1,3] " << p[3].min_d << " " << p[3].min_p << endl;
//    cout << "ans:\n";
    while (q --){
    	int opt,x;
    	scanf("%d%d",&opt,&x);
    	if (!opt)
    	  change(1,id[x]);
    	else{
    	    int res = ask(x);
    	    if (res) printf("%d\n",ask(x));
    	    else printf("-1\n");
        }
//        cout << "[1,3] " << p[3].min_d << " " << p[3].min_p << endl;
    }
	return 0;
}
2021/4/16 20:39
加载中...