LNOI2014 LCA 解題報告

2022-04-29 04:48:07 字數 2192 閱讀 3332

對於一棵 \(n\) 個節點的樹,給出 \(m\) 次詢問,每次給出 \(l,r,x\) ,求 \(\sum\limits_^r depth(lca(i,x))\) 。

\(n,m\le 5\times 10^4 , 1\le l\le r\le n , x\le n\)

一道不錯的題目。

說明有時候用一些其他的做法求乙個簡單的東西也可以幫助思考。

對於我,求lca都是用倍增來做的,但這題要求區間對於乙個節點x的lca的深度之和,如果只是在想用倍增的手法是做不出來的。

由於只是深度,並不需要得出切實的lca,這就給我們提供了乙個很好的方向。

考慮另外一種求lca深度的做法。

如果要求x和y的lca的深度,可以先將x到根的路徑全部賦值為1,再在統計y到根的路徑就可以得到lca的深度了。

這個做法有乙個很好的性質,那就是可加性。

所以只要把區間裡的所有節點到根的路徑都加1,最後在統計節點x到根的路徑的值就行了。

首先鏈上的修改和求和可以用樹鏈剖分做到 \(\mathcal\) ,考慮如何把區間給弄掉。

由於可加性和可減性,通過差分就可以將區間變為字首相減,然後將查詢拆成兩個,離線排序一下,從1號節點不斷修改到n號節點,如果遇到了對應的字首查詢,直接查詢儲存即可。

總效率 \(\mathcal\) ,精細實現可以做到 \(\mathcal\) 。

然而實際上這個將lca深度轉換為鏈上求和的方法也是一種差分思想,所以就出現了加強版的舊詞。

#include#include#includeusing namespace std;

const int m=5e4+5,jyy=201314;

void swap(int &x,int &y)

int min(int x,int y)

int n,q,fa[m],de[m],ans[m],pre[m];

struct quesq[m<<1];

int read()

while(ch>='0'&&ch<='9')

return x*y;

}int tot=0,first[m];

struct edgee[m<<1];

void add(int x,int y)

struct treetr[m<<2];

void pushup(int u)

void pushdown(int u)

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

void change(int u,int l,int r,int l,int r,int x)

pushdown(u);

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

change(u<<1,l,mid,l,r,x);

change(u<<1|1,mid+1,r,l,r,x);

pushup(u);

return ;

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

int num=0,st[m],en[m],son[m],top[m],dfn[m],size[m];

void dfs1(int u,int fa) }}

void dfs2(int u,int fa,int tp)

en[u]=num;

}void change(int x,int d)

change(1,1,n,st[1],st[x],d);

return ;

}int query(int x)

res=(res+query(1,1,n,st[1],st[x]))%jyy;

return res;

}bool cmp(ques x,ques y)

int main()

dfs1(1,0);

dfs2(1,0,1);

build(1,1,n);

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

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

sort(q+1,q+q*2+1,cmp);

int now=0;

for(int i=1;i<=2*q;i++)

ans[q[i].id]=(ans[q[i].id]+query(q[i].z)*q[i].zf+jyy)%jyy;

} for(int i=1;i<=q;i++)

}

LNOI2014 LCA 差分 樹剖

葉子最可愛啦qwq!每次詢問乙個區間和乙個點,求這個區間所有點和給定點的lca的深度和。深度和是吧。lca的深度和有乙個很優良的性質。你把乙個點到根的權值都 1,查另乙個點到根的權值就是這個深度。那問題轉化成了鏈加鏈求和。不過有q個詢問哦。怎麼辦呢?很明顯這個詢問應該被去掉。我們不乙個詢問乙個詢問查...

離線操作 樹鏈剖分 LNOI2014 LCA

題目描述 給出乙個n個節點的有根樹 編號為0到n 1,根節點為0 乙個點的深度定義為這個節點到根的距離 1。設dep i 表示點i的深度,lca i,j 表示i與j的最近公共祖先。有q次詢問,每次詢問給出l r z,求 l i r dep lca i,z sum dep lca i,z l i r ...

ZJOI2014 力 解題報告

zjoi2014 力 給出 n 個數 q i 定義 f j sum frac sum frac e i frac 求 e i i in 1,n 首先,提公因式,化簡可以得到,e j sum frac sum frac 把 q j 提出來後約掉 注意到式子可以分為兩個部分,這兩個部分中的因子可以分成 ...