JLOI2014 松鼠的新家 樹鏈剖分

2021-09-29 22:01:02 字數 1563 閱讀 9143

題解:本題主要考查樹鏈剖分。

簡要題意:一顆樹,有n個房間,並且有n-1根樹枝連線。小熊維尼先去a

1a_1

a1​,再去a

2a_2

a2​最後到a

na_n

an​,每走到乙個房間,他就可以從房間拿一塊糖果吃,最後乙個房間不用,求每個房間至少需要放多少個糖果。

1.樹鏈剖分:路過的點都加一,可以想到樹鏈剖分,每一次將a[i

]a[i]

a[i]

到a [i

+1

]a[i+1]

a[i+1]

的節點加一,在一次修改後,因為最後乙個房間不用加,所以避免重複終點要減1。線段樹模板區間加和區間查詢。**還是比較清楚的。

注意:本題資料較大,要用高效的讀寫(一般做這些題都要吧qwq),陣列一定要開四倍!

**如下:

#include#include#include#includeusing namespace std;

struct n

t[1126666];

struct e

e[1266666];

int a[1266666],h[1266666],siz[1266666],son[1266666],d[1266666];

int id[1266666],rk[1266666],top[1266666],f[1266666];

int p,num,n,m;

void pushup(int p)

void build(int p,int l,int r)

int mid=l+r>>1;

build(p<<1,l,mid);

build(p<<1|1,mid+1,r);

pushup(p);

}void lai(int p,int l,int r)

return ;

}void change(int p,int l,int r,int x,int y,int z)

lai(p,l,r);

int mid=l+r>>1;

if(x<=mid)change(p<<1,l,mid,x,y,z);

if(y>mid)change(p<<1|1,mid+1,r,x,y,z);

pushup(p);

}long long ask(int p,int l,int r,int x,int y)

void add(int start,int to)

void dfs1(int p,int fa,int deep)

}void dfs2(int p,int tp)

}int sum(int x,int y,int z)

int main()

//build(1,1,n);

dfs1(1,0,1);dfs2(1,1);

for(int i=1;i<=n-1;i++)

for(int i=1;i<=n;i++)

printf("%d\n",ask(1,1,n,id[i],id[i]));

return 0;

}

JLOI2014 松鼠的新家

裸的 樹鏈剖分 然而 並不用線段樹 求x,y的lca 後 在 x上標記加一,y上標記加一 lca標記減一,fa lca 標記減一 include int n int shunxv 300005 int to 600005 next 600005 head 600005 cnt void add in...

JLOI2014 松鼠的新家

time limit 10 sec memory limit 128 mb submit 1736 solved 840 松鼠的新家是一棵樹,前幾天剛剛裝修了新家,新家有n個房間,並且有n 1根樹枝連線,每個房間都可以相互到達,且倆個房間之間的路線都是唯一的。天哪,他居然真的住在 樹 上。松鼠想邀請...

JLOI2014 松鼠的新家

松鼠的新家是一棵樹,前幾天剛剛裝修了新家,新家有n個房間,並且有n 1根樹枝連線,每個房間都可以相互到達,且倆個房間之間的路線都是唯一的。天哪,他居然真的住在 樹 上。松鼠想邀請小熊維尼前來參觀,並且還指定乙份參觀指南,他希望維尼能夠按照他的指南順序,先去a1,再去a2,最後到an,去參觀新家。可是...