spoj375 Query on a tree

贴出代码,其中注释部分大多为自己打的时候的错误,以后回顾时稍微注意一下。

wrong! ——错误

forget!——忽略的

add!——其实这里面的阿得得是毫无意义的修改...(之前不知道错了哪里,就一顿乱改...ovo)


【bling!】

最终错因。

有一个地方把mid+1写成了mid+2........(尴尬尴尬

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

#define maxn (100000+10)
#define INF 0x7f7f7f7f

struct node{
	int to, next;
}e[maxn*3];
int head[maxn], cnt;

void addedge(int u, int v){
	e[cnt].to = v;
	e[cnt].next = head[u];
	head[u] = cnt++;
}
/*-----------------cut tree----------------------------*/
int dep[maxn], son[maxn], fa[maxn], top[maxn], siz[maxn], line[maxn], sum;//
void dfs1(int u, int pa, int depth){
	dep[u] = depth; fa[u] = pa; son[u] = 0; siz[u] = 1;//
	
	for(int i = head[u]; i != -1; i = e[i].next){
	    int v = e[i].to;
	    if(v == pa) continue;
	    dfs1(v, u, depth+1);
	    siz[u] += siz[v];
	    if(siz[v] > siz[son[u]]) son[u] = v;
	}
}
void dfs2(int u, int pa){
	line[u] = ++sum; top[u] = pa;
	if(son[u] != 0) dfs2(son[u], top[u]);
	for(int i = head[u]; i != -1; i = e[i].next)
	    if(e[i].to != son[u] && e[i].to != fa[u]) 
			dfs2(e[i].to, e[i].to);
}

/*---------------------seg tree------------------------*/
struct nodde{
    int l, r, val, mx;
/*add--*/int mid(){return (l + r) >> 1;}
}tree[maxn*2];

void build(int pos, int l, int r){
    tree[pos].l = l; tree[pos].r = r; tree[pos].mx = tree[pos].val = -INF;

/*forget!*/ if(l == r) return;  
 
//    int mid = tree[pos].l+((tree[pos].r-tree[pos].l) >> 1);
 	int mid = tree[pos].mid();   
/*wrong!    build(pos*2, tree[pos].l, mid);
    build(pos*2+1, mid+1, tree[pos].r);*/

    build(pos*2, l, mid);
    
/*wrong!    build(pos*2+1, mid+2, r)*/    
    
    build(pos*2+1, mid+1, r);
}

void update(int pos, int id, int w){
    if(tree[pos].l == tree[pos].r){
	    tree[pos].mx = tree[pos].val = w;
		return;
	}
//	int mid = tree[pos].l+((tree[pos].r-tree[pos].l) >> 1);
	int mid = tree[pos].mid();
	if(mid >= id) update(pos*2, id, w);
	else update(pos*2+1, id, w);

/*forget!*/tree[pos].mx = max(tree[pos*2].mx, tree[pos*2+1].mx);

}

int query(int pos, int L, int R){
    if(tree[pos].l >= L && tree[pos].r <= R) return tree[pos].mx;
//    int mid = tree[pos].l+((tree[pos].r-tree[pos].l) >> 1);
	int mid = tree[pos].mid();
    int ans = -INF;
    if(mid >= L) ans = max(ans, query(pos*2, L, R));
    if(mid < R) ans = max(ans, query(pos*2+1, L, R));
    
    return ans;
}

int lca(int u, int v){
	int ans = -INF;
	while(top[u] != top[v]){
	    if(dep[top[u]] < dep[top[v]]) swap(u, v);
	    ans = max(ans, query(1, line[top[u]], line[u]));
	    u = fa[top[u]];
	}

/*wrong!	if(dep[u] < dep[v]) swap(u, v);
	ans = max(ans, query(1, line[top[u]]+1, line[u]));*/

	if(dep[u] > dep[v]) swap(u, v);
	if(u != v) ans = max(ans, query(1, line[u]+1, line[v]));
	return ans;
}

int d[maxn][3];
int main(){
/*	freopen("test.in", "r", stdin);
	freopen("test.out","w",stdout);
*/	int _, n;
	scanf("%d", &_);
	
	while(_--){
		cnt = sum = 0;
		memset(head, -1, sizeof(head));
		
		scanf("%d", &n);
		for(int i = 1; i </*wrong! = */ n; i++){
		    scanf("%d%d%d", &d[i][0], &d[i][1], &d[i][2]);
		    addedge(d[i][0], d[i][1]);
		    addedge(d[i][1], d[i][0]);
		}
		
		dfs1(1, 1, 1);
		dfs2(1, 1);
		build(1, 2, n);
		
		for(int i = 1; i </*wrong! = */ n; i++){
/*wrong!if(d[i][0] > d[i][1]) swap(d[i][1], d[i][0]);*/
			if(dep[d[i][0]] > dep[d[i][1]]) swap(d[i][0], d[i][1]);		    
		    update(1, /*wrong! d[i][1] */line[d[i][1]], d[i][2]);
		}
		
		char s[10];
		while(1){
			scanf("%s", s);
			if(s[0] == 'D') break;
			if(s[0] == 'Q'){
				int a, b;
				scanf("%d%d", &a, &b);
				printf("%d\n", lca(a, b));
			}
			else{
				int a, b;
				scanf("%d%d", &a, &b);
				update(1, line[d[a][1]], b);
			}
		}
		printf("\n");
	}
	
	return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值