poj3237 樹鏈剖分

2021-07-23 10:12:03 字數 1635 閱讀 9583

wa了n發,

每次取相反數的時候,都需要交換最大值和最小值,這樣才能維護動態的平衡,因為lazy標誌的原因,取相反數,沒有更新到底,所以如果只維護乙個最大值會出問題。

#include 

#include

#include

const

int n=50010;

using

namespace

std;

struct node

e[n];

struct d

edge[n<<1];

int cnt,tim,head[n];

int a[n];

int siz[n],son[n],fa[n],tid[n],dep[n],top[n];

void intt()

void dfs1(int u,int pre,int de)

}void add(int u,int v)

#define ls l,mid,rt<<1

#define rs mid+1,r,rt<<1|1

int sum[n<<2],sum1[n<<2],lazy[n<<2];

void changeval(int t)

void up(int rt)

void down(int rt)

}void build(int l,int r,int rt)

int mid=(l+r)>>1;

build(ls);

build(rs);

up(rt);

}void update(int pos,int val,int l,int r,int rt)

int mid=(l+r)>>1;

down(rt);

if(pos<=mid) update(pos,val,ls);

else update(pos,val,rs);

up(rt);

}int query(int l,int r,int l,int r,int rt)

void update1(int l,int r,int l,int r,int rt)

int mid=(l+r)>>1;

down(rt);

if(mid>=l) update1(l,r,ls);

if(midint main()

dfs1(1,1,1);

dfs2(1,1);

for(int i=1;iif(dep[e[i].u]else a[tid[e[i].u]]=e[i].w;

build(1,n-1,1);

while(1)

if(dep[aa]>dep[bb]) swap(aa,bb);

if(aa!=bb) ma=max(ma,query(tid[aa]+1,tid[bb],1,n-1,1));

printf("%d\n",ma);

}else

if(cmd[0]=='c')

else

if(cmd[0]=='n')

if(dep[aa]>dep[bb]) swap(aa,bb);

if(aa!=bb) update1(tid[aa]+1,tid[bb],1,n-1,1);}}

}}

poj 3237 樹鏈剖分

對樹有三種操作 q a b 詢問a b路徑的最大值 n a b 對a b路徑上的數進行取反操作 a a c a b 將第a條邊的值改為b 對於取反操作,記錄區間的最大和最小值和標記k,更新線段即可。pragma comment linker,stack 1024000000,1024000000 i...

POJ 3237(樹鏈剖分)

這道題算是樹鏈剖分的模板題吧 其實也是我過的第一道樹鏈剖分的題目 歷盡千辛萬苦,終於把兩百多行的 敲出來了,ac的一瞬間還是挺爽的。在學會了樹鏈剖分之後,這道題不算很難的了,主要是在區間取反的部分注意一下細節。樹鏈剖分 挺長的,很多地方都是容易寫錯。我也是通過討論區的acmer給出的資料找出一些錯誤...

poj 3237 樹鏈剖分 線段樹

題意 給一棵樹,三種操作。將第i條邊的權值改為v,將a到b的路徑上的邊的權值全部取反,求a到b路徑上邊的權值的最大值。思路 明顯的樹鏈剖分,加上線段樹的操作。因為有取反的操作所以每個區間要記錄最大值和最小值。查詢兩點間的路徑時,用求公共祖先的方式去求。include include includec...