POJ 3237
题目大意:指定一颗树上有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的更多相关文章
- HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- poj 3237 Tree [LCA] (树链剖分)
poj 3237 tree inline : 1. inline 定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高. 2. 很明显,类 ...
- poj 3237 Tree(树链拆分)
题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...
- HDU 3966 & POJ 3237 & HYSBZ 2243 & HRBUST 2064 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- cogs 1583. [POJ 3237] 树的维护 树链剖分套线段树
1583. [POJ 3237] 树的维护 ★★★★ 输入文件:maintaintree.in 输出文件:maintaintree.out 简单对比时间限制:5 s 内存限制:128 ...
- POJ 3237:Tree(树链剖分)
http://poj.org/problem?id=3237 题意:树链剖分.操作有三种:改变一条边的边权,将 a 到 b 的每条边的边权都翻转(即 w[i] = -w[i]),询问 a 到 b 的最 ...
- poj 3237 Tree 树链剖分
题目链接:http://poj.org/problem?id=3237 You are given a tree with N nodes. The tree’s nodes are numbered ...
- POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)
题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...
- ●POJ 3237 Tree
题链: http://poj.org/problem?id=3237 题解: LCT 说一说如何完成询问操作就好了(把一条链的边权变成相反数的操作可以类比着来): 首先明确一下,我们把边权下放到点上. ...
- POJ 3237 树链剖分
题目链接:http://poj.org/problem?id=3237 题意:给定一棵n个结点n-1条边的树. 每条边都是一个边权. 现在有4种操作 1:CHANGE I V:把(输入的)第i条边的边 ...
随机推荐
- 【ufldl tutorial】Convolution and Pooling
卷积的实现: 对于每幅图像,每个filter,首先从W中取出对应的filter: filter = squeeze(W(:,:,filterNum)); 接下来startercode里面将filter ...
- datagrid实现行的上移和下移
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- EI中国
这里可以看到EI收录的所有的中国期刊:http://lib.sytu.edu.cn/files/zwwxx/2009-EI-china.htm
- Spring的线程池ThreadPoolTaskExecutor使用案例
1.Sping配置文件 <!-- 线程池配置 --> <bean id="threadPool" class="org.springframework. ...
- c++程序编码
c++程序中涉及到中文字符的输入输出以及其他操作经常会出现乱码.乱码主要是由于程序的源文件编码.可执行文件编码以及程序运行环境的编码不匹配导致.比如,c++源程序文件编码为GB18030, 在源程序中 ...
- unicode 和 utf-8 的关系和解释
首先一个字节就是8个晶体管同时发出的信号集, unicode就是一套编码,所有的字符都用2个字节表示,不像gbk和gb2312既保持了以前的ansi/ascii的字符单个字节编码,有发明了两个字节保存 ...
- parent relation column can't be updated LESSON_EXTENDED_ATTRIBUTE->LESSON_ID
MyCat 中 作为分片的主键不允许更新 , 需要设置为null,调用updateSelectiveByPrimaryKey来更新数据 parent relation column can't be ...
- mac 下获取 os x 的系统版本,使用 oc cocoa
mac 下获取 os x 的系统版本,使用 oc cocoa 1: #import <CoreServices/CoreServices.h> SInt32 major, minor, b ...
- js encodeURI方法认识
很早就知道js中encodeURI方法,也很早就用过,但是每次看到它总感觉有些陌生,因为不知道到底是什么原理,和普通的编码到底什么关系, 今天在查看w3c api时又遇到了她,正好有空就多看了几眼,突 ...
- 集成代码编辑器ACE的经验
ACE是最流行的在线代码编辑器之一,在CanTK的集成开发环境GameBuilder里也使用了ACE.ACE的功能非常强大,但是由于使用方法不当,大家反映GameBuilder的代码编辑器不好用.最近 ...