葉子最可愛啦qwq!
每次詢問乙個區間和乙個點,求這個區間所有點和給定點的lca的深度和。
深度和是吧。
lca的深度和有乙個很優良的性質。你把乙個點到根的權值都+1,查另乙個點到根的權值就是這個深度。
那問題轉化成了鏈加鏈求和。
不過有q個詢問哦。怎麼辦呢?
很明顯這個詢問應該被去掉。
我們不乙個詢問乙個詢問查詢。
我們直接從1號點開始加入貢獻。對於乙個詢問,加到l-1時統計一下,加到r時統計一下,然後兩者減減就行。
利用了差分的思想。
當然是樹剖+線段樹。
warning:不要像我一樣,跳top時交換了top沒交換自己。
#includeusing namespace std;
#define in read()
int in
while(isdigit(ch))return cnt*f;
}const int mod=201314;
struct nodet[200003];
int n,m;
int first[100003],nxt[200003],to[200003],tot;
void add(int a,int b)
int id[100003],top[100003],son[100003],size[100003],dep[100003],fa[100003];
void pushup(int u)
void pushdown(int u)
}int queryseg(int u,int ql,int qr)
void segmo(int u,int ql,int qr,int key)
struct bilique[100003];int cnt;
int ans1[100003],ans2[100003];
void dfs1(int u,int faa)
}void dfs2(int u,int tp)
}void build(int u,int l,int r)int mid=(l+r)>>1;
build(u*2,l,mid);build(u*2+1,mid+1,r);
}bool cm(bili a,bili b)
int main()
build(1,1,n);dfs1(1,0);dfs2(1,1);
//for(int i=1;i<=n;i++)cout/debug(1,1,n);
for(int i=1;i<=m;i++)
sort(que+1,que+cnt+1,cm);
for(int i=1,pos=0;i<=cnt;i++)
que[i].ans=query(1,que[i].z);
if(que[i].flag)(ans[que[i].belong]+=que[i].ans)%=mod;
else ((ans[que[i].belong]-=que[i].ans)+=mod)%=mod;
} for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
return 0;
}
離線操作 樹鏈剖分 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 ...
LNOI2014 LCA 解題報告
對於一棵 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 一道不錯的題目。說明有時候用一些其他的做法求乙個簡單的東西也可以幫助思考。對於我,求lc...
LCA 樹鏈剖分
剛打完lca板子,寫個東西記下 dfs第一遍求出 結點i的深度,以i為根的子樹大小,結點i的父親,並求出重鏈 dfs第二遍求出 結點i所在重鏈的鏈頂 如果在重鏈上 開始lca,兩個點往上找,深度大的點就往上跳,這個點如果在重鏈上,就跳到所在重鏈的鏈頂的父親處,在輕鏈上,就直接跳到自己父親上 洛谷lc...