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