过了样例但boom 0 的蒟蒻求助
查看原帖
过了样例但boom 0 的蒟蒻求助
234224
青鸟_Blue_Bird楼主2020/8/11 19:52

蒟蒻写过很多树剖题了,但卡了这么久了的还是第一个。

大概思路:线段树两个标记,一个维护当前区间有没有黑点(标记为1),否则为0.第二个标记则维护最靠左的那个黑点的编号,如果没有黑点则为inf。

然后我就boom 0 了。

#include <bits/stdc++.h>
using namespace std;
#define N 100010

template <class T>
inline void read(T& a){
	T x = 0, s = 1;
	char c = getchar();
	while(!isdigit(c)){
		if(c == '-') s = -1;
		c = getchar();
	}
	while(isdigit(c)){
		x = x * 10 + (c ^ '0');
		c = getchar();
	}
	a = x * s;
	return ;
}

struct node{
	int v, next;
	
	node(int v = 0, int next = 0){
		this -> v = v;
		this -> next = next;
		return ;
	}
	
} t[N << 1];
int f[N];
int n, Q;

int bian = 0;
inline void add(int u, int v){
	t[++bian] = node(v, f[u]), f[u] = bian;
	t[++bian] = node(u, f[v]), f[v] = bian;
	return ;
}

int top[N], fa[N], deth[N], son[N], siz[N];
int dfn[N], id = 0, rev[N];

#define v t[i].v
void dfs1(int now, int father){
	siz[now] = 1;
	fa[now] = father;
	deth[now] = deth[father] + 1;
	for(int i = f[now]; i; i = t[i].next){
		if(v != father){
			dfs1(v, now);
			siz[now] += siz[v];
			if(siz[v] > siz[son[now]])
				son[now] = v;
		}
	}
	return ;
}

void dfs2(int now, int tp){
	top[now] = tp;
	dfn[now] = ++id;
	rev[id] = now;
	if(!son[now]) return ;
	dfs2(son[now], tp);
	for(int i = f[now]; i; i = t[i].next){
		if(v != fa[now] && v != son[now])
			dfs2(v, v);
	}
	return ;
}
#undef v

const int inf = (int)2e9;
struct tree{
	int w, front;
	
	tree(int w = 0, int front = inf){
		this -> w = w;
		this -> front = front;
		return ;
	}
	
} e[N << 2];


inline void pushup(int o){
	e[o].w = max(e[o << 1].w, e[o << 1 | 1].w);
	if(!e[o].w) e[o].front = inf;  // no black point
	else if(e[o << 1].front != inf) e[o].front = e[o << 1].front;
	else if(e[o << 1 | 1].front != inf) e[o].front = e[o << 1 | 1].front;
	return ;
}

void build(int o, int l, int r){
	if(l == r){
		e[o].w = 0;
		e[o].front = inf;
		return ;
	}
	int mid = l + r >> 1;
	build(o << 1, l, mid);
	build(o << 1 | 1, mid + 1, r);
	pushup(o);
	return ;
}

void update(int o, int l, int r, int x){
	if(l > x || r < x) return ;
	if(l == r && l == x){
		e[o].w ^= 1;
		if(e[o].w) e[o].front = l;
		else e[o].front = inf;
		return ;
	}
	int mid = l + r >> 1;
	update(o << 1, l, mid, x);
	update(o << 1 | 1, mid + 1, r, x);
	pushup(o);
	return ;
}

int query(int o, int l, int r, int in, int end){
	if(l > end || r < in) return inf;
	if(l >= in && r <= end){
		return e[o].front;
	}
	int mid = l + r >> 1;
	int lson = query(o << 1, l, mid, in, end);
	int rson = query(o << 1 | 1, mid + 1, r, in, end);
	if(lson != inf) return lson;
	else return rson;
}

int ask_min(int x, int y){
	int sum = inf;
	while(top[x] != top[y]){
		if(deth[top[x]] < deth[top[y]]) swap(x, y);
		int temp = query(1, 1, n, dfn[top[x]], dfn[x]);
		if(temp != inf) sum = temp;
		x = fa[top[x]];
	}
	if(deth[x] > deth[y]) swap(x, y);
	int temp = query(1, 1, n, dfn[x], dfn[y]);
	if(temp != inf)
		sum = temp;
	return sum == inf ? -1 : dfn[sum];
}

int main(){
//	freopen("hh.txt", "r", stdin);
	read(n), read(Q);
	for(int i = 1; i < n; i++){
		int x, y;
		read(x), read(y);
		add(x, y);
	}
	dfs1(1, 0);
	dfs2(1, 0);
	build(1, 1, n);
	while(Q--){
		int flag, x, ans;
		read(flag);
		switch (flag){
			case 0:
				read(x);
				update(1, 1, n, dfn[x]);
				break;
			case 1:
				read(x);
				printf("%d\n", ask_min(1, x));
 		}
	}
	return 0;
}
2020/8/11 19:52
加载中...