题目大意:指定一颗树上有3个操作:询问操作,询问a点和b点之间的路径上最长的那条边的长度;取反操作,将a点和b点之间的路径权值都取相反数;变化操作,把某条边的权值变成指定的值。
 #include <cstdio>
#include <iostream>
#include <cstring> using namespace std;
#define N 10010
#define ls o<<1
#define rs o<<1|1
#define define_m int m=(l+r)>>1
const int INF = ;
int first[N] , k;
struct Edge{
int x , y , next , w;
Edge(){}
Edge(int x , int y , int next , int w):x(x),y(y),next(next),w(w){}
}e[N<<]; void add_edge(int x ,int y , int w)
{
e[k] = Edge(x , y , first[x] , w);
first[x] = k++;
} int sz[N] , son[N] , dep[N] , fa[N] , num , id[N] , top[N];
void dfs(int u , int f , int d)
{
sz[u] = , fa[u] = f , son[u] = , dep[u] = d;
int maxn = ;
for(int i=first[u] ; ~i ; i=e[i].next){
int v = e[i].y;
if(v == f) continue;
dfs(v , u , d+);
sz[u] += sz[v];
if(maxn<sz[v]) maxn = sz[v] , son[u] = v;
}
} void dfs1(int u , int f , int head)
{
id[u] = ++num , top[u] = head;
if(son[u]) dfs1(son[u] , u , head);
for(int i=first[u] ; ~i ; i=e[i].next){
int v = e[i].y;
if(v == f || v==son[u]) continue;
dfs1(v , u , v);
}
} int mx[N<<] , mn[N<<] , neg[N<<] , val[N]; void push_down(int o)
{
if(neg[o]<){
neg[ls]*=neg[o] , neg[rs]*=neg[o];
int tmp;
tmp = mx[ls] , mx[ls] = -mn[ls] , mn[ls] = -tmp;
tmp = mx[rs] , mx[rs] = -mn[rs] , mn[rs] = -tmp;
neg[o] = ;
}
} void push_up(int o)
{
mx[o] = max(mx[ls] , mx[rs]);
mn[o] = min(mn[ls] , mn[rs]);
} void build(int o , int l , int r)
{
neg[o] = ;
if(l==r){
mx[o] = mn[o] = val[l];
return ;
}
define_m;
build(ls , l , m);
build(rs , m+ , r);
push_up(o);
} void change(int o , int l , int r , int p , int v)
{
if(l==r){
mx[o] = mn[o] = v;
return;
}
push_down(o);
define_m;
if(m>=p) change(ls , l , m , p , v);
else change(rs , m+ , r , p , v);
push_up(o);
} void update(int o , int l , int r , int s , int t)
{
if(l>=s && r<=t){
int tmp;
tmp = mx[o] , mx[o] = -mn[o] , mn[o] = -tmp;
neg[o] *= -;
return ;
}
push_down(o);
define_m;
if(m>=s) update(ls , l , m , s , t);
if(m<t) update(rs , m+ , r , s , t);
push_up(o);
} int query(int o , int l , int r , int s , int t)
{
if(l>=s && r<=t) return mx[o];
push_down(o);
define_m;
int ans = -INF;
if(m>=s) ans=max(ans , query(ls , l , m , s , t));
if(m<t) ans=max(ans , query(rs , m+ , r , s , t));
return ans;
}
int n , u , v , w;
char str[]; void negatePath(int u , int v)
{
int top1 = top[u] , top2 = top[v];
while(top1!=top2)
{
if(dep[top1]<dep[top2]){
swap(top1 , top2);
swap(u , v);
}
update( , , num , id[top1] , id[u]);
u = fa[top1];
top1 = top[u];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u , v);
update( , , num , id[son[v]] , id[u]);
}
} int calPath(int u , int v)
{
int top1 = top[u] , top2 = top[v];
int ret = -INF;
while(top1!=top2){
if(dep[top1]<dep[top2]){
swap(top1 , top2);
swap(u , v);
}
ret = max(ret , query( , , num , id[top1] , id[u]));
u = fa[top1];
top1 = top[u];
}
if(u!=v){
if(dep[u]<dep[v]) swap(u , v);
ret = max(ret , query( , , num , id[son[v]] , id[u]));
}
return ret;
} int main()
{
// freopen("in.txt" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
scanf("%d" , &n);
memset(first , - , sizeof(first));
k=;
for(int i= ; i<n- ; i++){
scanf("%d%d%d" , &u ,&v , &w);
add_edge(u , v , w);
add_edge(v , u , w);
}
num = ;
dfs( , , );
dfs1( , , );
for(int i= ; i<n ; i++){
int j=i<< , x=e[j].x , y=e[j].y;
if(fa[x]!=y) val[id[y]] = e[j].w;
else val[id[x]] = e[j].w;
}
build( , , num);
while(scanf("%s" , str)){
if(str[] == 'D') break;
if(str[] == 'C'){
scanf("%d%d" , &u , &v);
u--;
int x = e[u*].x , y = e[u*].y , pos;
if(fa[x]!=y) pos = id[y];
else pos = id[x];
change( , , num , pos , v);
}
else if(str[] == 'N'){
scanf("%d%d" , &u , &v);
negatePath(u , v);
}
else{
scanf("%d%d" , &u , &v);
int ret = calPath(u , v);
printf("%d\n" , ret);
}
}
}
return ;
}

POJ 3237的更多相关文章

  1. HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分

    树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...

  2. poj 3237 Tree [LCA] (树链剖分)

    poj 3237 tree inline : 1. inline 定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高. 2. 很明显,类 ...

  3. poj 3237 Tree(树链拆分)

    题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...

  4. HDU 3966 & POJ 3237 & HYSBZ 2243 & HRBUST 2064 树链剖分

    树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...

  5. cogs 1583. [POJ 3237] 树的维护 树链剖分套线段树

    1583. [POJ 3237] 树的维护 ★★★★   输入文件:maintaintree.in   输出文件:maintaintree.out   简单对比时间限制:5 s   内存限制:128 ...

  6. POJ 3237:Tree(树链剖分)

    http://poj.org/problem?id=3237 题意:树链剖分.操作有三种:改变一条边的边权,将 a 到 b 的每条边的边权都翻转(即 w[i] = -w[i]),询问 a 到 b 的最 ...

  7. poj 3237 Tree 树链剖分

    题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...

  8. POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)

    题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...

  9. ●POJ 3237 Tree

    题链: http://poj.org/problem?id=3237 题解: LCT 说一说如何完成询问操作就好了(把一条链的边权变成相反数的操作可以类比着来): 首先明确一下,我们把边权下放到点上. ...

  10. POJ 3237 树链剖分

    题目链接:http://poj.org/problem?id=3237 题意:给定一棵n个结点n-1条边的树. 每条边都是一个边权. 现在有4种操作 1:CHANGE I V:把(输入的)第i条边的边 ...

随机推荐

  1. 浅谈 MVP in Android

    一.概述 对于MVP(Model View Presenter),大多数人都能说出一二:“MVC的演化版本”,“让Model和View完全解耦”等等.本篇博文仅是为了做下记录,提出一些自己的看法,和帮 ...

  2. Android广播BroadcastReceiver 一

    Android 系统里定义了各种各样的广播,如电池的使用状态,电话的接收和短信的接收,开机启动都会产生一个广播.当然用户也可以自定义自己的广播. 既然说到广播,那么必定有一个广播发送者,以及广播接收器 ...

  3. iOS 开发之 Xcode6 installation failed invalid argument!

    1.运行模拟器的时候 报出: installation failed invalid argument! 原因分析: 我把Bundle indentifier 置为空了! http://stackov ...

  4. 货币金额的计算 - Java中的BigDecimal

    在<Effective Java>这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal.,而且使 ...

  5. Maven最佳实践:划分模块

    http://juvenshun.iteye.com/blog/305865 ************************************* "分天下为三十六郡,郡置守,尉,监& ...

  6. android 存储

    总共四种:SharedPreferences,文件存储,SQLite数据库,ContentProvider,网络存储 1.sharedPreferences:适合存储少量数据,而且存取的格式简单,采用 ...

  7. 【ubuntu java】java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory

    先检查了环境变量PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/loca ...

  8. [转]Material Design Library 23.1.0的新变化与代码实战

    Design Library出来已经快有一个月了,当时大概看了一下介绍这个新版本变化的译文,内容不多,给我印象最深的就是Percent lib.AppBarLayout 和NavigationView ...

  9. ubuntu server nginx 安装与配置

    ubuntu server nginx 安装与配置 一:关于nginx http://wiki.ubuntu.org.cn/Nginx http://nginx.org/cn http://wiki. ...

  10. 用ildasm/ilasm修改IL代码

    原文地址:http://www.cnblogs.com/dudu/archive/2011/05/17/ildasm_ilasm_il.html 在开发中遇到这样一个场景,需要修改一个dll文件(.N ...