這道題算是樹鏈剖分的模板題吧(其實也是我過的第一道樹鏈剖分的題目)。歷盡千辛萬苦,終於把兩百多行的**敲出來了,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...