Problem Tree (POJ3237)

题目大意

  给定一颗树,有边权。

  要求支持三种操作:

    操作一:更改某条边的权值。

    操作二:将某条路径上的边权取反。

    操作三:询问某条路径上的最大权值。

解题分析

  树链剖分+线段树。练手题。

参考程序

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std; #define V 100008
#define E 200008
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define INF 2000000000 int cnt,n;
int size[V],dep[V],fa[V],son[V],top[V],w[V],rk[V],a[V]; struct line{
int u,v,w,nt;
}eg[E];
int lt[V],sum; void adt(int u,int v,int w){
eg[++sum].u=u; eg[sum].v=v; eg[sum].w=w; eg[sum].nt=lt[u]; lt[u]=sum;
}
void add(int u,int v,int w){
adt(u,v,w); adt(v,u,w);
} struct segment_tree{
// 单点修改 区间取反 区间询问
int mx[V<<],mn[V<<],lazy[V<<];
void pushup(int rt){
mx[rt]=max(mx[rt<<],mx[rt<<|]);
mn[rt]=min(mn[rt<<],mn[rt<<|]);
}
void pushdown(int rt){
if (lazy[rt]){
lazy[rt<<]^=;
lazy[rt<<|]^=;
int t=mx[rt<<];
mx[rt<<]=-mn[rt<<];
mn[rt<<]=-t;
t=mx[rt<<|];
mx[rt<<|]=-mn[rt<<|];
mn[rt<<|]=-t;
lazy[rt]=;
}
}
void build(int l,int r,int rt){
lazy[rt]=;
if (l==r){
mn[rt]=mx[rt]=a[rk[l]];
return;
}
int m=(l+r)/;
build(lson);
build(rson);
pushup(rt);
}
void update_1(int x,int val,int l,int r,int rt){
if (l==r){
mx[rt]=val;
mn[rt]=val;
return;
}
pushdown(rt);
int m=(l+r)/;
if (x <= m) update_1(x,val,lson);
if (m < x) update_1(x,val,rson);
pushup(rt);
}
void update_2(int L,int R,int l,int r,int rt){
if (L<=l && r<=R){
int t=mx[rt];
mx[rt]=-mn[rt];
mn[rt]=-t;
lazy[rt]^=;
return;
}
pushdown(rt);
int m=(l+r)/;
if (L <= m) update_2(L,R,lson);
if (m < R) update_2(L,R,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt){
if (L<=l && r<=R){
return mx[rt];
}
pushdown(rt);
int m=(l+r)/;
int res=-INF;
if (L <= m) res=max(res,query(L,R,lson));
if (m < R) res=max(res,query(L,R,rson));
return res;
}
}T; void dfs_1(int u){
dep[u]=dep[fa[u]]+; size[u]=; son[u]=;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u]) continue;
a[v]=eg[i].w;
fa[v]=u;
dfs_1(v);
size[u]+=size[v];
if (size[v]>size[son[u]]) son[u]=v;
}
}
void dfs_2(int u,int tp){
top[u]=tp; w[u]=++cnt; rk[cnt]=u;
if (son[u]) dfs_2(son[u],tp);
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u] || v==son[u]) continue;
dfs_2(v,v);
}
}
void find_1(int x,int y){
int res=-INF;
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res=max(res,T.query(w[top[x]],w[x],,n,));
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
res=max(res,T.query(w[x]+,w[y],,n,));
printf("%d\n",res);
}
void find_2(int x,int y){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
T.update_2(w[top[x]],w[x],,n,);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
T.update_2(w[x]+,w[y],,n,);
} int main(){
int tt;
scanf("%d",&tt);
while (tt--){
sum=; cnt=;
memset(lt,,sizeof(lt));
scanf("%d",&n);
for (int i=;i<n;i++){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
add(u,v,w);
}
scanf("\n");
dfs_1();
dfs_2(,);
T.build(,n,);
char s[];
for (scanf("%s",s);strcmp(s,"DONE")!=;scanf("%s",s)){
int x,y;
scanf("%d %d\n",&x,&y);
if (strcmp(s,"QUERY")==){
find_1(x,y);
}
if (strcmp(s,"CHANGE")==){
int u=eg[x*].u , v=eg[x*].v;
if (dep[u]<dep[v]) T.update_1(w[v],y,,n,);
else T.update_1(w[u],y,,n,);
}
if (strcmp(s,"NEGATE")==){
find_2(x,y);
}
}
}
}

POJ3237 (树链剖分+线段树)的更多相关文章

  1. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  2. POJ3237 Tree 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  7. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  8. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  9. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

随机推荐

  1. form程序的界面修改

    做主题视频库的界面的修改工作,是b/s端的窗口,是由form窗口生成,如下截图: 主要有三个方面,1.左侧菜单栏宽度固定,不随整个窗口大变化而变化.2.导出excel按钮的位置的移动,不管整个窗口是变 ...

  2. css改变图片的颜色

    参考大神张鑫旭:http://www.zhangxinxu.com/wordpress/2016/06/png-icon-change-color-by-css/ 主要知识点:border-right ...

  3. ASP.NET访问Access的连接字符串配置

    由于Access是文件数据库,所以在ASP.NET需要能映射访问到Access文件: 方式一:appSettings中设置连接字符串 web.config的配置 <appSettings> ...

  4. OL/SQL编程练习

    create or replace procedure pr_first is --一个变量 v_a ) := '总有一天我的生命将走到尽头'; --一个常量 c_b constant ) := '而 ...

  5. 解决visualsvn监听ip 错误的问题

    系统重启+休眠之类的,弄几次,莫名其妙的svn就连接不上了, 有时候启动不起,有时候是启动连接不上,发现监听的ip错了 TCP    [::]:443               [::]:0     ...

  6. 神奇的Noip模拟试题一试 2 排队

    2 排队 (lineup.pas/.c/.cpp) [问题描述] 小sin所在的班有n名同学,正准备排成一列纵队,但他们不想按身高从矮到高排,那样太单调,太没个性.他们希望恰好有k对同学是高的在前,矮 ...

  7. JSON初步

    1.什么是JSON (1)JSON(Java Script Object Notation)是一种轻量级的数据交换语言, 以文本字符串为基础,且易于让人阅读 XML就是一个重量级的数据交换语言 (2) ...

  8. SPOJ SUBLEX 求第k小子串

    题目大意: 对于一个给定字符串,找到其所有不同的子串中排第k小的子串 先构建后缀自动机,然后我们可以将整个后缀自动机看做是一个DAG图,那么我们先进行拓扑排序得到 *b[N] 对于每个节点记录一个sc ...

  9. vmware 下的linux的host only上网配置

    1.首先在Vm中将网络设置为Host-only. 2.在windows下,打开网络邻居,会见到如下界面,其中负责联网的是本地连接,Vm1是host-only连接,VM2是Nat连接方式,首先将VM1. ...

  10. ODI中显示us7ascii字符集的测试

    安装oracle DB时,选择的字符集:美国.英语.US7ASCII. 在不设置nls_lang的情况,插入中文,成功,但存进去的是乱码,select看到也是??(无论后面再怎么设置nls_lang) ...