当前位置:网站首页>poj 3237 Tree(樹鏈拆分)
poj 3237 Tree(樹鏈拆分)
2022-07-05 21:42:00 【全棧程序員站長】
大家好,又見面了,我是全棧君,今天給大家准備了Idea注册碼。
題目大意:給定一棵樹,三種操作:
- CHANGE i v:將i節點權值變為v
- NEGATE a b:將ab路徑上全部節點的權值變為相反數
- QUERY a b:查詢ab路徑上節點權值的最大值。
解題思路:樹鏈剖分。然後用線段樹維護節點權值,成端更新查詢。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 10005;
const int INF = 0x3f3f3f3f;
int id, far[maxn], son[maxn], cnt[maxn], idx[maxn], top[maxn], dep[maxn];
int N, en, first[maxn], jump[maxn * 2], val[maxn];
struct Edge {
int u, v, w;
void set (int u, int v, int w) {
this->u = u;
this->v = v;
this->w = w;
}
}ed[maxn * 2];
void dfs_fir (int u, int pre, int d) {
dep[u] = d;
far[u] = pre;
cnt[u] = 1;
son[u] = 0;
for (int i = first[u]; i + 1; i = jump[i]) {
int v = ed[i].v;
if (v == pre)
continue;
dfs_fir(v, u, d + 1);
cnt[u] += cnt[v];
if (cnt[son[u]] < cnt[v])
son[u] = v;
}
}
void dfs_sec(int u, int rot) {
idx[u] = id++;
top[u] = rot;
if (son[u])
dfs_sec(son[u], rot);
for (int i = first[u]; i + 1; i = jump[i]) {
int v = ed[i].v;
if (v == far[u] || v == son[u])
continue;
dfs_sec(v, v);
}
}
#define lson(x) ((x)<<1)
#define rson(x) (((x)<<1)|1)
int lc[maxn << 2], rc[maxn << 2], filp[maxn << 2], Ma[maxn << 2], Mi[maxn << 2];
inline void maintain (int u) {
filp[u] ^= 1;
swap(Ma[u], Mi[u]);
Ma[u] = -Ma[u];
Mi[u] = -Mi[u];
}
inline void pushup(int u) {
Ma[u] = max(Ma[lson(u)], Ma[rson(u)]);
Mi[u] = min(Mi[lson(u)], Mi[rson(u)]);
}
inline void pushdown (int u) {
if (filp[u]) {
maintain(lson(u));
maintain(rson(u));
filp[u] = 0;
}
}
void build (int u, int l, int r) {
lc[u] = l;
rc[u] = r;
filp[u] = 0;
if (l == r) {
Ma[u] = Mi[u] = val[l];
return;
}
int mid = (l + r) / 2;
build(lson(u), l, mid);
build(rson(u), mid + 1, r);
pushup(u);
}
void modify (int u, int x, int w) {
if (lc[u] == x && rc[u] == x) {
Ma[u] = Mi[u] = w;
return;
}
pushdown(u);
int mid = (lc[u] + rc[u]) / 2;
if (x <= mid)
modify(lson(u), x, w);
else
modify(rson(u), x, w);
pushup(u);
}
void splay(int u, int l, int r) {
if (l <= lc[u] && rc[u] <= r) {
maintain(u);
return;
}
pushdown(u);
int mid = (lc[u] + rc[u]) / 2;
if (l <= mid)
splay(lson(u), l, r);
if (r > mid)
splay(rson(u), l, r);
pushup(u);
}
int query (int u, int l, int r) {
if (l <= lc[u] && rc[u] <= r)
return Ma[u];
pushdown(u);
int mid = (lc[u] + rc[u]) / 2, ret = -INF;
if (l <= mid)
ret = max(ret, query(lson(u), l, r));
if (r > mid)
ret = max(ret, query(rson(u), l, r));
pushup(u);
return ret;
}
inline void add_Edge(int u, int v, int w) {
ed[en].set(u, v, w);
jump[en] = first[u];
first[u] = en++;
}
void init () {
en = 0;
id = 1;
memset(first, -1, sizeof(first));
scanf("%d", &N);
int u, v, w;
for (int i = 0; i < N - 1; i++) {
scanf("%d%d%d", &u, &v, &w);
add_Edge(u, v, w);
add_Edge(v, u, w);
}
dfs_fir(1, 0, 0);
dfs_sec(1, 1);
for (int i = 0; i < N - 1; i++) {
int t = i * 2;
if (dep[ed[t].u] < dep[ed[t].v])
swap(ed[t].u, ed[t].v);
val[idx[ed[t].u]] = ed[t].w;
}
build(1, 1, N);
}
int query (int u, int v) {
int p = top[u], q = top[v], ret = -INF;
while (p != q) {
if (dep[p] < dep[q]) {
swap(p, q);
swap(u, v);
}
ret = max(ret, query(1, idx[p], idx[u]));
u = far[p];
p = top[u];
}
//printf("%d %d\n", u, v);
if (u == v)
return ret;
if (dep[u] > dep[v])
swap(u, v);
ret = max(ret, query(1, idx[son[u]], idx[v]));
return ret;
}
void modify (int u, int v) {
int p = top[u], q = top[v];
while (p != q) {
if (dep[p] < dep[q]) {
swap(p, q);
swap(u, v);
}
splay(1, idx[p], idx[u]);
u = far[p];
p = top[u];
}
if (u == v)
return;
if (dep[u] > dep[v])
swap(u, v);
splay(1, idx[son[u]], idx[v]);
}
void solve () {
int u, v;
char op[20];
while (scanf("%s", op), strcmp(op, "DONE") != 0) {
scanf("%d%d", &u, &v);
if (op[0] == 'C')
modify(1, idx[ed[u*2-2].u], v);
else if (op[0] == 'Q')
printf("%d\n", query(u, v));
else
modify(u, v);
}
}
int main () {
int cas;
scanf("%d", &cas);
while (cas--) {
init();
solve();
}
return 0;
}版權聲明:本文博客原創文章。博客,未經同意,不得轉載。
發布者:全棧程序員棧長,轉載請注明出處:https://javaforall.cn/117584.html原文鏈接:https://javaforall.cn
边栏推荐
- QML reported an error expected token ";", expected a qualified name ID
- 使用Aspect制作全局异常处理类
- Huawei game multimedia service calls the method of shielding the voice of the specified player, and the error code 3010 is returned
- 初级软件测试必问面试题
- Efficiency difference between row first and column first traversal of mat data types in opencv
- 华为游戏多媒体服务调用屏蔽指定玩家语音方法,返回错误码3010
- Interview questions for basic software testing
- Selenium gets the verification code image in DOM
- Parker driver maintenance COMPAX controller maintenance cpx0200h
- PostGIS installation geographic information extension
猜你喜欢

Reading and writing operations of easyexcel

总结出现2xx、3xx、4xx、5xx状态码的原因

华为游戏多媒体服务调用屏蔽指定玩家语音方法,返回错误码3010

基于 Ingress Controller 在集群外访问 Zadig 自测环境(最佳实践)

Opérations de lecture et d'écriture pour easyexcel

Wood board ISO 5660-1 heat release rate mapping test

2.2 basic grammar of R language

uni-app 蓝牙通信

張麗俊:穿透不確定性要靠四個“不變”

Golang (1) | from environmental preparation to quick start
随机推荐
Golang (1) | from environmental preparation to quick start
Pointer parameter passing vs reference parameter passing vs value parameter passing
HDU 4391 Paint The Wall 段树(水
MMAP
Why can't Chinese software companies produce products? Abandon the Internet after 00; Open source high-performance API gateway component of station B | weekly email exclusive to VIP members of Menon w
selenium 查找b或p标签的内容
Analysis and test of ModbusRTU communication protocol
ESP32
力扣------经营摩天轮的最大利润
JMeter installation under win7
int GetMonth( ) const throw( );后面的throw( )什么意思?
How can Huawei online match improve the success rate of player matching
Poj3414广泛搜索
MATLAB | App Designer·我用MATLAB制作了一款LATEX公式实时编辑器
校招期间 准备面试算法岗位 该怎么做?
Exercise 1 simple training of R language drawing
Teach yourself to train pytorch model to Caffe (I)
Detailed explanation of memset() function usage
初级软件测试必问面试题
PVC plastic sheets BS 476-6 determination of flame propagation properties