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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ4381[POI2015]Odwiedziny——分块+长链剖分

發布時間:2025/5/22 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ4381[POI2015]Odwiedziny——分块+长链剖分 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

給定一棵n個點的樹,樹上每條邊的長度都為1,第i個點的權值為a[i]。
Byteasar想要走遍這整棵樹,他會按照某個1到n的全排列b走n-1次,第i次他會從b[i]點走到b[i+1]點,并且這一次的步伐大小為c[i]。
對于一次行走,假設起點為x,終點為y,步伐為k,那么Byteasar會從x開始,每步往前走k步,如果最后不足k步就能到達y,那么他會一步走到y。
請幫助Byteasar統計出每一次行走時經過的所有點的權值和。

輸入

第一行包含一個正整數n(2<=n<=50000)。表示節點的個數。
第二行包含n個正整數,其中第i個數為a[i](1<=a[i]<=10000),分別表示每個點的權值。
接下來n-1行,每行包含兩個正整數u,v(1<=u,v<=n),表示u與v之間有一條邊。
接下來一行包含n個互不相同的正整數,其中第i個數為b[i](1<=b[i]<=n),表示行走路線。
接下來一行包含n-1個正整數,其中第i個數為c[i](1<=c[i]<n),表示每次行走的步伐大小。

輸出

包含n-1行,每行一個正整數,依次輸出每次行走時經過的所有點的權值和

樣例輸入

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

樣例輸出

10
6
10
5
       因為k的大小不確定,所以分情況來做。設p=sqrt(n),當k<=p時,可以預處理出f[i][j]表示i節點以j步伐一直往上走,直到走到根節點(i節點的深度如果不是k的倍數,根節點不計入)為止能得到的點權和,查詢時直接求就好了.當k>p時,就要暴力往上走了,可以用重鏈剖分來實現,單次查詢時間復雜度是O(logn+√n),但有一種時間復雜度更優的做法——長鏈剖分,因為長鏈剖分可以O(1)查詢一個點的k級祖先,因此最多爬√n次,單次查詢時間復雜度O(√n)。如何實現參見->長鏈剖分 #include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; int n; int x,y; int tot; int mask; int b[50010]; int a[50010]; int k[50010]; int d[50010]; int st[50010]; int mx[50010]; int to[100010]; int son[50010]; int top[50010]; int head[50010]; int next[100010]; int f[50010][17]; int up[50010][300]; vector<int>s[50010]; vector<int>t[50010]; void add(int x,int y) {tot++;next[tot]=head[x];head[x]=tot;to[tot]=y; } void dfs(int x) {d[x]=d[f[x][0]]+1;mx[x]=d[x];for(int i=1;i<=16;i++){if(f[x][i-1]){f[x][i]=f[f[x][i-1]][i-1];}else{break;}}int fx=x;for(int i=1;i<=mask;i++){fx=f[fx][0];up[x][i]=a[x]+up[fx][i];}for(int i=head[x];i;i=next[i]){if(to[i]!=f[x][0]){f[to[i]][0]=x;dfs(to[i]);mx[x]=max(mx[x],mx[to[i]]);if(mx[to[i]]>mx[son[x]]){son[x]=to[i];}}} } void dfs2(int x,int tp) {top[x]=tp;if(son[x]){dfs2(son[x],tp);}for(int i=head[x];i;i=next[i]){if(to[i]!=f[x][0]&&to[i]!=son[x]){dfs2(to[i],to[i]);}} } void find(int x) {int rt=x;int len=mx[x]-d[x];x=f[rt][0];while(d[rt]-d[x]<=len&&x){s[rt].push_back(x);x=f[x][0];}x=rt;while(son[x]){t[rt].push_back(son[x]);x=son[x];} } int find_ancestor(int x,int k) {if(k==0){return x;}if(d[x]<=k){return 0;}x=f[x][st[k]];k-=(1<<st[k]);if(k==0){return x;}if(k==d[x]-d[top[x]]){return top[x];}if(k<d[x]-d[top[x]]){return t[top[x]][d[x]-d[top[x]]-k-1];}return s[top[x]][k-d[x]+d[top[x]]-1]; } int lca(int x,int y) {if(d[x]<d[y]){swap(x,y);}int dep=d[x]-d[y];for(int i=0;i<=16;i++){if((dep&(1<<i))!=0){x=f[x][i];}}if(x==y){return x;}for(int i=16;i>=0;i--){if(f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}}return f[x][0]; } int query(int x,int y,int step) {int res=0;int anc=lca(x,y);int lx=d[x]-d[anc];int ly=d[y]-d[anc];if(step>mask){res+=a[x]+a[y];while(lx>step){x=find_ancestor(x,step);res+=a[x];lx-=step;}if(lx+ly-1>=step){y=find_ancestor(y,lx+ly-(lx+ly-1)/step*step);res+=a[y];ly=(lx+ly-1)/step*step-lx;while(ly>step){y=find_ancestor(y,step);res+=a[y];ly-=step;}}if(x!=anc&&y!=anc&&(lx==step||ly==step)) {res+=a[anc];}}else{if(lx+ly<=step){res=a[x]+a[y];}else{res+=a[y];y=find_ancestor(y,lx+ly-(lx+ly-1)/step*step);ly=(lx+ly-1)/step*step-lx;res+=up[x][step]-up[find_ancestor(x,(lx/step)*step+step)][step];if(ly>=0){res+=up[y][step]-up[find_ancestor(y,(ly/step)*step+step)][step];}if(lx%step==0){res-=a[anc];}}}return res; } int main() {scanf("%d",&n);mask=sqrt(n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);}for(int i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);}dfs(1);dfs2(1,1);for(int i=1;i<=n;i++){if(i==top[i]){find(i);}}st[1]=0;for(int i=2;i<=n;i++){st[i]=st[i>>1]+1;}for(int i=1;i<=n;i++){scanf("%d",&b[i]);}for(int i=1;i<n;i++){scanf("%d",&k[i]);}for(int i=1;i<n;i++){printf("%d\n",query(b[i],b[i+1],k[i]));} }

轉載于:https://www.cnblogs.com/Khada-Jhin/p/9581321.html

總結

以上是生活随笔為你收集整理的BZOJ4381[POI2015]Odwiedziny——分块+长链剖分的全部內容,希望文章能夠幫你解決所遇到的問題。

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