POJ 3237(樹鏈剖分)

2021-07-05 04:23:48 字數 2028 閱讀 1699

這道題算是樹鏈剖分的模板題吧(其實也是我過的第一道樹鏈剖分的題目)。歷盡千辛萬苦,終於把兩百多行的**敲出來了,ac的一瞬間還是挺爽的。

在學會了樹鏈剖分之後,這道題不算很難的了,主要是在區間取反的部分注意一下細節。樹鏈剖分**挺長的,很多地方都是容易寫錯。我也是通過討論區的acmer給出的資料找出一些錯誤的地方。

#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

//樹鏈剖分

const int maxn = 10005;

int dep[maxn],siz[maxn],fa[maxn],id[maxn],son[maxn],num[maxn],top[maxn];

int fir[maxn],vv[maxn<<1],val[maxn<<1],nxt[maxn<<1],e;

int ll[maxn<<2],rr[maxn<<2],maxed[maxn<<2],minn[maxn<<2];

bool negative[maxn<<2];

int idx;

struct edge

edge(){}

};vectorvec;

void add(int a,int b,int v)

void dfs(int cur,int pre)

siz[cur]+=siz[v];

} son[cur]=sonn;

}void dfs2(int cur,int tp)

}void push_down(int i)

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

int mid=(l+r)>>1,ls=i<<1,rs=ls|1;

build(ls,l,mid);

build(rs,mid+1,r);

maxed[i]=max(maxed[ls],maxed[rs]);

minn[i]=min(minn[ls],minn[rs]);

}void updatepos(int i,int pos,int _val)

push_down(i);//不能漏掉這一句

int mid=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;

if(pos<=mid) updatepos(ls,pos,_val);

else updatepos(rs,pos,_val);

maxed[i]=max(maxed[ls],maxed[rs]);

minn[i]=min(minn[ls],minn[rs]);

}void negaseg(int i,int l,int r)

push_down(i);

int mid=(ll[i]+rr[i])>>1,ls=i<<1,rs=ls|1;

if(l>mid) negaseg(rs,l,r);

else if(r<=mid) negaseg(ls,l,r);

else

maxed[i]=max(maxed[ls],maxed[rs]);

minn[i]=min(minn[ls],minn[rs]);

}int query_max(int i,int l,int r)

int query_min(int i,int l,int r)

//initialize the upper edge of one node

void init()

void nega_tree(int u,int v)

int main()

{ int t;

scanf("%d",&t);

while(t--)

{ int n;

scanf("%d",&n);

for(int i=1;i<=n;i++)fir[i]=-1,num[i]=0;

e=0;idx=0;

vec.clear();

int a,b,v;

for(int i=1;i

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

poj3237 樹鏈剖分

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

poj 3237 樹鏈剖分 線段樹

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