两个更新操作,一个将第i条路径权值改为w,一个是将a-b之间所有路径权值取反。

一个查询操作,求a-b之间路径中权值最大的边。

很容易想到维护一个最大最小值,取反就是把最大最小取反交换一下。

开始遇到一个问题就是我把根节点赋值0,上一道题求和没问题,但是这道题会出问题,于是线段树建树的时候从2开始建的,第一次尝试这么写,不过也没什么问题。

wa了一天。。。。

一开始的错是pushdown的时候没有把子节点的fg更新,于是我改了fg[lson]=fg[rson]=1。。。。。。。。

就这样。。。。我对着这份代码看了几个小时。。。。。找数据。。。后来自己写了发对拍。。。。
后来终于忍不了了。。。。找了别人的代码。。。。

哦,应该是fg[lson] ^= 1;  fg[rson] ^= 1;

我果然不会线段树。。。。。

mdzz

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
const int N = ; //
struct Edge {
int to, next, cost, id;
} edge[N*];
int head[N], cntE;
void addedge(int u, int v, int w, int id) {
edge[cntE].to = v; edge[cntE].next = head[u]; edge[cntE].cost = w; edge[cntE].id = id; head[u] = cntE++;
edge[cntE].to = u; edge[cntE].next = head[v]; edge[cntE].cost = w; edge[cntE].id = id; head[v] = cntE++;
}
//
int dep[N], sz[N], fa[N], son[N], son_cost[N];
int road[N];
void dfs1(int u, int par, int d) {
dep[u] = d; sz[u] = ; fa[u] = par;
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v != par) {
road[edge[i].id] = v;
dfs1(v, u, d+);
sz[u] += sz[v];
if (son[u] == - || sz[v] > sz[son[u]]) {
son[u] = v;
son_cost[u] = edge[i].cost;
}
}
}
}
int top[N], dfn[N], rk[N], idx;
int a[N];
void dfs2(int u, int rt, int cost) {
top[u] = rt; dfn[u] = ++idx; a[idx] = cost;
if (son[u] == -) return;
dfs2(son[u], rt, son_cost[u]);
for (int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if (v != fa[u] && v != son[u]) dfs2(v, v, edge[i].cost);
}
} //
int mx[N<<], fg[N<<], mi[N<<];
#define lson o<<1
#define rson o<<1|1 void pushdown(int o) {
if (fg[o]) {
fg[lson] ^= ;
fg[rson] ^= ;
int tmp = mx[lson];
mx[lson] = -mi[lson];
mi[lson] = -tmp;
tmp = mx[rson];
mx[rson] = -mi[rson];
mi[rson] = -tmp;
fg[o] = ;
}
} void pushup(int o) {
mx[o] = max(mx[lson], mx[rson]);
mi[o] = min(mi[lson], mi[rson]);
} void build(int o, int l, int r) {
fg[o] = ;
if (l == r) {
mx[o] = a[l];
mi[o] = a[l];
} else {
int mid = (l+r) >> ;
build(lson, l, mid);
build(rson, mid+, r);
pushup(o);
}
} void CHANGE(int o, int l, int r, int v, int w) {
if (l == r) {
mi[o] = mx[o] = w;
} else {
pushdown(o);
int mid = (l + r) >> ;
if (mid >= v) CHANGE(lson, l, mid, v, w);
else CHANGE(rson, mid+, r, v, w);
pushup(o);
}
} void nega(int o, int l, int r, int L, int R) {
if (l >= L && r <= R) {
fg[o] ^= ;
int tmp = mx[o];
mx[o] = -mi[o];
mi[o] = -tmp;
return;
}
pushdown(o);
int mid = (l+r) >> ;
if (mid >= L) nega(lson, l, mid, L, R);
if (mid < R) nega(rson, mid+, r, L, R);
pushup(o);
} void NEGATE(int x, int y, int n) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
nega(, , n, dfn[top[x]], dfn[x]);
x = fa[top[x]];
}
if (x == y) return ;
if (dep[x] > dep[y]) swap(x, y);
nega(, , n, dfn[son[x]], dfn[y]);
} int query(int o, int l ,int r, int L, int R) {
if (l >= L && r <= R) {
return mx[o];
}
pushdown(o);
int mid = (l+r) >> ;
int ans = -(<<);
if (L <= mid) ans = max(ans, query(lson, l, mid, L, R));
if (R > mid) ans = max(ans, query(rson, mid+, r, L, R));
pushup(o);
return ans;
} int QUERY(int x, int y, int n) {
if (x == y) return ;
int ans = -(<<);
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
ans = max(ans, query(, , n, dfn[top[x]], dfn[x]));
x = fa[top[x]];
}
if (x == y) return ans;
if (dep[x] > dep[y]) swap(x, y);
ans = max(ans, query(, , n, dfn[son[x]], dfn[y])); // 注意这里是son[x]
return ans;
} void init() {
idx = cntE = ;
memset(head, -, sizeof head);
memset(son, -, sizeof son);
} // 区间更新 点更新 区间查询
int main() {
int n, T;
scanf("%d",&T);
int cas = ;
while (T--) {
scanf("%d", &n); init();
int u, v, w;
for (int i = ; i < n; ++i) scanf("%d%d%d", &u, &v, &w), addedge(u, v, w, i);
dfs1(, , ); dfs2(, , ); build(, , n);
char op[];
while (~scanf("%s", op)) {
if (*op == 'D') break;
scanf("%d%d", &u, &v);
if (*op == 'Q') printf("%d\n", QUERY(u, v, n));
else if (*op == 'C') CHANGE(, , n, dfn[road[u]], v);
else NEGATE(u, v, n);
}
}
return ;
}

一组数据

/**
2

7
1 2 1
2 3 7
3 4 8
4 5 6
5 6 9
6 7 1
N 4 7
C 2 3
N 1 7
C 2 7
N 1 5
C 4 7
D

6
1 2 8
2 3 8
3 4 7
4 5 2
5 6 10
N 6 1
C 1 2
N 3 6
N 4 1
N 1 6
Q 2 6
D

Output:
8
1
7
8

10
-10
7
*/

POJ3237-Tree (树链剖分,线段树区间更新+点更新+区间查询)的更多相关文章

  1. POJ3237 Tree 树链剖分 线段树

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

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

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

  3. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  4. 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 ...

  5. POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )

    POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...

  6. 【CF725G】Messages on a Tree 树链剖分+线段树

    [CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...

  7. 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并

    题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...

  8. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

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

  9. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

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

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

随机推荐

  1. ios开发之 MPMoviePlayerController 视频播放器

    MPMoviePlayerController 与AVAudioPlayer有点类似,前者播放视频,后者播放音频,不过也有很大不同,MPMoviePlayerController 可以直接通过远程UR ...

  2. Ubuntu 安装mod_python配置Apache2

    在Ubuntu上搭建Python运行环境,mod_python是不可少的(据说mod_swgi也是可以的,没有亲测).使用命令安装mod_python. 安装: apt-get install lib ...

  3. axis : java.lang.NoSuchMethodError

    Hi friends,Iam getting the following error when deploying my app in jboss error.Iam new to axis .can ...

  4. ADO和DAO的区别

    ADO(ACTIVEX DATA OBJECTS)应用层的数据访问接口ODBC 数据库驱动接口OLE DB 系统级数据访问接口DAO (DATA ACCESS OBJECTS) 对象的数据访问接口AD ...

  5. UVALive 4043 Ants(二分图完美匹配)

    题意:每个蚁群有自己的食物源(苹果树),已知蚂蚁靠气味辨别行进方向,所以蚁群之间的行动轨迹不能重叠.现在给出坐标系中n个蚁群和n棵果树的坐标,两两配对,实现以上要求.输出的第 i 行表示第 i 个蚁群 ...

  6. UVA 11090 Going in Cycle!!(二分答案+判负环)

    在加权有向图中求平均权值最小的回路. 一上手没有思路,看到“回路”,第一想法就是找连通分量,可又是加权图,没什么好思路,那就转换题意:由求回路权值->判负环,求最小值->常用二分答案. 二 ...

  7. [反汇编练习] 160个CrackMe之014

    [反汇编练习] 160个CrackMe之014. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...

  8. RTP封装h264

    网络抽象层单元类型 (NALU): NALU头由一个字节组成,它的语法如下: +---------------+      |0|1|2|3|4|5|6|7|      +-+-+-+-+-+-+-+ ...

  9. Delphi 函数参数修饰中的var 、out和const

      (1)var修饰符 添加var 是地址传递,会修改原有的变量 var s: string; begin S := 'Hello'; ChangeSVar(s); ShowMessage(S); e ...

  10. duilib corner属性的贴图技巧——让图片自动贴到控件的的某一边或者一角并自适应控件的大小

    转载请说明原出处,谢谢~~ Duilib给控件贴图功能可以附带多个属性,各个属性的配合可以达到许多效果.以下是duilib支持的所有贴图属性: 贴图描述: Duilib的表现力丰富很大程度上得益于贴图 ...