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条边的边 ...
随机推荐
- Hbase之缓存扫描加快读取速度
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...
- iOS设置app应用程序文件共享
1.iOSapp应用程序文件共享 当我们用itnues连接到设备时,在应用程序栏目下面,文件共享下,点击 对应的程序,即可以在程序右边栏目里面看到应用程序共享的数据, 此时,我们可以通过右下角的 添加 ...
- 将cantk runtime嵌入到现有的APP中
1,先取cantk-runtime-demos到本地: git clone https://github.com/drawapp8/cantk-runtime-demos 2,创建一个Android ...
- Django开发博客- 部署
安装Git Git是一个被大量程序员使用的”版本控制系统”.此软件可以跟踪任何时间文件的改变,这样你以后可以随时召回某个特定版本. windows系统下面可以下载git-scm安装.除了第5步”Adj ...
- SqlServer关闭与启用标识(自增长)列
1 --添加新列 2 ALTER TABLE TABLENAME ADD ID int 3 --赋值 4 UPDATE TABLENAME SET ID = IDENTITY_ID 5 --删除标识列 ...
- hibernate annotation注解方式来处理映射关系
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...
- JavaScript自定义类和对象的方法
备注:JavaScript中没有类class的概念,一般把原型对象看作类 1. 工厂方法--使用new Object创建对象并添加相关属性 var Obj = new Object; ...
- zoj3822 Domination(概率dp)
Domination Time Limit: 8 Seconds Memory Limit: 131072 KB Special Judge Edward is the headm ...
- hdu----(2084)数塔(dp)
数塔 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...
- hdu----(5053)the Sum of Cube(签到题,水体)
the Sum of Cube Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...