日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【LNOI2014】【BZOJ3626】NOIp2018模拟(三) LCA

發布時間:2025/4/9 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LNOI2014】【BZOJ3626】NOIp2018模拟(三) LCA 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Description

給出一個n個節點的有根樹(編號為0到n-1,根節點為0)。一個點的深度定義為這個節點到根的距離+1。
設$dep[i]$表示點i的深度,$lca(i,j)$表示i與j的最近公共祖先。
有q次詢問,每次詢問給出l,r,z,求$\sum\limits_{i=l}^{r}dep[lca(i,z)]$。
(即求在$[l,r]$區間內的每個節點i與z的最近公共祖先的深度之和)

$n,q<=50000$

Input

第一行2個整數n,q。
接下來n-1行,分別表示點1到點n-1的父節點編號。
接下來q行,每行3個整數l,r,z。

Output

輸出q行,每行表示一個詢問的答案。每個答案對201314取模輸出

Sample Input

5 2
0
0
1
1
1 4 3
1 4 2

Sample Output

8
5

?

這題不算很難,但是看到正解的方法很有趣,就記錄一下~

考慮暴力,每次詢問把z到根的所有節點打上標記,枚舉i的時候直接往根找第一個有標記的點,然后統計深度即可。

然而復雜度明顯是大于$O(n^2q)$的,顯然不能接受,容易發現如果把深度看成點權,那么統計深度就相當于把z到根的每個節點權值都加一,然后枚舉時統計根節點到i的權值和。使用樹鏈剖分可以降到$O(nqlog^2n)$,但是還是會超時。

考慮進一步優化,發現詢問可以差分,拆成$[1,l-1]$和$[1,r]$兩個詢問,進一步可以發現對答案有貢獻的點只會在$lca(i,z)$以上,因此把每個i到根路徑上的結點權值加一,再統計z到根節點的權值和,得出的答案是相同的。再結合差分,每次直接將$[1,l-1]$或$[1,r]$中所有節點到根節點路徑上的點權值加一,然后統計z到根節點的權值和,按照dfs序區間修改+區間查詢,用樹鏈剖分加線段樹可以做到$O(qlog^2n)$,用LCT可以做到$O(qlogn)$

注意long long

代碼:

?

1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define mod 201314 7 using namespace std; 8 typedef long long ll; 9 struct edge{ 10 int v,next; 11 }a[200001]; 12 struct task{ 13 int r,z,id,ok; 14 }q[200001]; 15 int n,qq,u,v,z,tmp=0,qqq=0,tot=0,tim=0,head[100001],son[100001],siz[100001],fa[100001],dep[100001],dfn[100001],top[100001]; 16 ll t[500001],laz[500001],tv[500001],ans[100001],anss; 17 bool cmp(task a,task b){ 18 return a.r<b.r; 19 } 20 void add(int u,int v){ 21 a[++tot].v=v; 22 a[tot].next=head[u]; 23 head[u]=tot; 24 } 25 void dfs1(int u,int f,int dpt){ 26 dep[u]=dpt; 27 fa[u]=f; 28 siz[u]=1; 29 for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){ 30 int v=a[tmp].v; 31 if(!dep[v]){ 32 dfs1(v,u,dpt+1); 33 siz[u]+=siz[v]; 34 if(siz[v]>siz[son[u]]||son[u]==-1)son[u]=v; 35 } 36 } 37 } 38 void dfs2(int u,int tp){ 39 dfn[u]=++tim; 40 top[u]=tp; 41 if(son[u]!=-1)dfs2(son[u],tp); 42 for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){ 43 int v=a[tmp].v; 44 if(v!=son[u])dfs2(v,v); 45 } 46 } 47 void pushup(int u){ 48 t[u]=t[u*2]+t[u*2+1]; 49 } 50 void pushdown(int u){ 51 if(laz[u]){ 52 laz[u*2]+=laz[u]; 53 laz[u*2+1]+=laz[u]; 54 t[u*2]+=tv[u*2]*laz[u]; 55 t[u*2+1]+=tv[u*2+1]*laz[u]; 56 laz[u]=0; 57 } 58 } 59 void build(int l,int r,int u){ 60 if(l==r){ 61 tv[u]=1; 62 return; 63 } 64 int mid=(l+r)/2; 65 build(l,mid,u*2); 66 build(mid+1,r,u*2+1); 67 tv[u]=tv[u*2]+tv[u*2+1]; 68 } 69 void updata(int l,int r,int u,int L,int R,int v){ 70 if(L<=l&&r<=R){ 71 t[u]+=(ll)tv[u]*v; 72 laz[u]+=v; 73 return; 74 } 75 int mid=(l+r)/2; 76 pushdown(u); 77 if(L<=mid)updata(l,mid,u*2,L,R,v); 78 if(mid<R)updata(mid+1,r,u*2+1,L,R,v); 79 pushup(u); 80 } 81 ll query(int l,int r,int u,int L,int R){ 82 if(L<=l&&r<=R){ 83 return t[u]; 84 } 85 int mid=(l+r)/2,ans=0; 86 pushdown(u); 87 if(L<=mid)ans+=query(l,mid,u*2,L,R); 88 if(R>mid)ans+=query(mid+1,r,u*2+1,L,R); 89 return ans; 90 } 91 void work(int u){ 92 while(u){ 93 int v=top[u]; 94 updata(1,n,1,dfn[v],dfn[u],1); 95 u=fa[v]; 96 } 97 } 98 ll _work(int u){ 99 ll ans=0; 100 while(u){ 101 int v=top[u]; 102 ans+=query(1,n,1,dfn[v],dfn[u]); 103 u=fa[v]; 104 } 105 return ans; 106 } 107 int main(){ 108 memset(son,-1,sizeof(son)); 109 memset(head,-1,sizeof(head)); 110 scanf("%d%d",&n,&qq); 111 for(int i=1;i<n;i++){ 112 scanf("%d",&u); 113 add(u+1,i+1); 114 } 115 dfs1(1,0,1); 116 dfs2(1,1); 117 build(1,n,1); 118 for(int i=1;i<=qq;i++){ 119 scanf("%d%d%d",&u,&v,&z); 120 u++,v++,z++; 121 q[++qqq]=(task){u-1,z,i,-1}; 122 q[++qqq]=(task){v,z,i,1}; 123 } 124 sort(q+1,q+qqq+1,cmp); 125 for(int i=1;i<=qqq;i++){ 126 while(tmp<q[i].r){ 127 work(++tmp); 128 } 129 ans[q[i].id]+=(ll)q[i].ok*_work(q[i].z); 130 } 131 for(int i=1;i<=qq;i++){ 132 printf("%lld\n",ans[i]%mod); 133 } 134 return 0; 135 }

?

?

?

轉載于:https://www.cnblogs.com/dcdcbigbig/p/9268231.html

總結

以上是生活随笔為你收集整理的【LNOI2014】【BZOJ3626】NOIp2018模拟(三) LCA的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。