zoukankan      html  css  js  c++  java
  • 【SPOJ】375. Query on a tree(树链剖分)

    http://www.spoj.com/problems/QTREE/

    这是按边分类的。

    调试调到吐,对拍都查不出来,后来改了下造数据的,拍出来了。囧啊啊啊啊啊啊

    时间都花在调试上了,打hld只用了半小时啊囧。

    第一次打边分类真没注意一个地方。

    就是当fx==fy后,没有判断x==y,然后这是边分类,获得的是父亲的下标,果断错。。

    囧,一定要记住这个错误。

    #include <cstring>
    #include <cstdio>
    #include <iostream>
    using namespace std;
    #define lc x<<1
    #define rc x<<1|1
    #define lson l, m, lc
    #define rson m+1, r, rc
    #define MID (l+r)>>1
    #define read(x) x=getint()
    #define dbg(x) cout << #x << "=" << x << endl
    inline const int max(const int& a, const int& b) { return a>b?a:b; }
    inline int getint() { char c; int ret=0, k=1; for(c=getchar(); c<'0' || c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0' && c<='9'; c=getchar()) ret=ret*10+c-'0'; return k*ret; }
    
    const int N=50010, oo=~0u>>1;
    struct Ed { int u, v, w; }e[N];
    int ihead[N], inext[N<<1], to[N<<1], cnt;
    int fa[N], sz[N], son[N], top[N], dep[N], id[N], mx[N*5], num[N], tot, L, R, key, n;
    
    inline void pushup(const int &x) { mx[x]=max(mx[lc], mx[rc]); }
    void build(const int &l, const int &r, const int &x) {
    	if(l==r) { mx[x]=num[l]; return; }
    	int m=MID;
    	build(lson); build(rson);
    	pushup(x); 
    }
    void update(const int &l, const int &r, const int &x) {
    	if(l==r) { mx[x]=key; return; }
    	int m=MID;
    	if(L<=m) update(lson); if(m<R) update(rson); pushup(x);
    }
    int getmax(const int &l, const int &r, const int &x) {
    	if(L<=l && r<=R) return mx[x];
    	int m=MID, ret=oo+1;
    	if(L<=m) ret=max(ret, getmax(lson)); if(m<R) ret=max(ret, getmax(rson)); return ret;
    }
    void dfs1(const int &u) {
    	sz[u]=1; int v;
    	for(int i=ihead[u]; i; i=inext[i]) if(fa[u]!=(v=to[i])) {
    		fa[v]=u; dep[v]=dep[u]+1;
    		dfs1(v);
    		sz[u]+=sz[v];
    		if(sz[v]>sz[son[u]]) son[u]=v;
    	}
    }
    void dfs2(const int &u, const int &tp) {
    	id[u]=++tot; top[u]=tp;
    	if(son[u]) dfs2(son[u], tp);
    	for(int i=ihead[u]; i; i=inext[i]) if(fa[u]!=to[i] && to[i]!=son[u]) dfs2(to[i], to[i]);
    }
    inline int getmax(int x, int y) {
    	int fx=top[x], fy=top[y], ret=oo+1;
    	while(fx!=fy) {
    		if(dep[fx]<dep[fy]) { swap(x, y); swap(fx, fy); }
    		L=id[fx]; R=id[x];
    		ret=max(ret, getmax(2, n, 1));
    		x=fa[fx]; fx=top[x];
    	}
    	if(dep[x]>dep[y]) swap(x, y);
    	if(x!=y) L=id[x]+1; R=id[y]; //这里,如果不特判的话,L会>R,然后线段树那里果断死循环
    	return max(ret, getmax(2, n, 1));
    }
    inline void add(const int &u, const int &v) {
    	inext[++cnt]=ihead[u]; ihead[u]=cnt; to[cnt]=v;
    	inext[++cnt]=ihead[v]; ihead[v]=cnt; to[cnt]=u;
    }
    int main() {
    	int c=getint(), a, b; char ch;
    	while(c--) {
    		read(n);
    		tot=cnt=0;
    		memset(ihead, 0, sizeof(int)*(n+10));
    		memset(fa, 0, sizeof(int)*(n+10));
    		memset(son, 0, sizeof(int)*(n+10));
    		for(int i=1; i<n; ++i) {
    			read(e[i].u); read(e[i].v); read(e[i].w);
    			add(e[i].u, e[i].v);
    		}
    		dfs1(1); dfs2(1, 1);
    		for(int i=1; i<n; ++i) {
    			if(dep[e[i].u]>dep[e[i].v]) swap(e[i].u, e[i].v);
    			num[id[e[i].v]]=e[i].w;
    		}
    		build(2, n, 1);
    		for(ch=getchar(); ch<'A' || ch>'Z'; ch=getchar());
    		while(ch!='D') {
    			read(a); read(b);
    			if(ch=='C') { key=b; L=R=id[e[a].v]; update(2, n, 1); }
    			else printf("%d
    ", getmax(a, b));
    			for(ch=getchar(); ch<'A' || ch>'Z'; ch=getchar());
    		}
    	}
    	return 0;	
    }
    

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.

    We will ask you to perfrom some instructions of the following form:

    • CHANGE i ti : change the cost of the i-th edge to ti
      or
    • QUERY a b : ask for the maximum edge cost on the path from node a to node b

    Input

    The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.

    For each test case:

    • In the first line there is an integer N (N <= 10000),
    • In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),
    • The next lines contain instructions "CHANGE i ti" or "QUERY a b",
    • The end of each test case is signified by the string "DONE".

    There is one blank line between successive tests.

    Output

    For each "QUERY" operation, write one integer representing its result.

    Example

    Input:
    1
    
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE
    
    Output:
    1
    3
    
  • 相关阅读:
    PlantUML —— 应用于 Eclipse 的简单快速的 UML 编辑软件
    PlantUML类图
    Java 基于log4j的日志工具类
    RabbitMQ Hello world(二)
    redis lua 初体验
    mysql 批处理 innodb_flush_at_trx_commit 测试分析
    mysql 服务日志 5.7.29
    redis 浅谈事务
    redis list 基本操作
    redis hash 基本操作
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/3923507.html
Copyright © 2011-2022 走看看