bzoj4458 GTY的OJ (优先队列+倍增)
把超级钢琴放到了树上。
这次不用主席树了..本来以为会好写一点没想到细节更多(其实是树上细节多)
为了方便,对每个点把他的那个L,R区间转化成两个深度a,b,表示从[a,b)选一个最小的前缀和(到根的和)减掉
为了更加方便,编号变为2~N+1,然后把2连到1上,1作为一个假根,权值为0
然后倍增去找那个a和b,记一记最小值的位置,然后劈开再加回到优先队列里就行了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 const int maxn=5e5+10; 7 const ll inf=1e12; 8 9 inline ll rd(){ 10 ll x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 struct Node{ 17 int x,l,r,m;ll v; 18 }; 19 bool operator < (Node a,Node b){return a.v<b.v;} 20 bool operator > (Node a,Node b){return a.v>b.v;} 21 int N,M,L,R; 22 int fa[maxn][22],mi[maxn][22],dep[maxn]; 23 ll mn[maxn][22],v[maxn]; 24 priority_queue<Node> q; 25 26 inline ll getrmq(int x,int l,int r,int &m){ 27 if(l<=0) return -inf; 28 ll vx=v[x]; 29 for(int i=19;i>=0;i--){ 30 if(fa[x][i]&&dep[fa[x][i]]>=l) 31 x=fa[x][i]; 32 } 33 ll f=inf; 34 for(int i=19;i>=0;i--){ 35 if(fa[x][i]&&dep[fa[x][i]]>=r){ 36 if(mn[x][i]<f) f=mn[x][i],m=dep[mi[x][i]]; 37 x=fa[x][i]; 38 } 39 } 40 if(dep[x]>r&&mn[x][0]<f) f=mn[x][0],m=dep[mi[x][0]]; 41 // printf("%d %d\n",vx,f); 42 return vx-f; 43 } 44 45 int main(){ 46 //freopen("","r",stdin); 47 int i,j,k; 48 N=rd(); 49 for(i=2;i<=N+1;i++){ 50 fa[i][0]=rd()+1; 51 }dep[1]=1; 52 for(i=2;i<=N+1;i++) v[i]=v[fa[i][0]]+rd(),dep[i]=dep[fa[i][0]]+1; 53 M=rd(),L=rd(),R=rd(); 54 55 for(i=1;i<=N+1;i++){ 56 mn[i][0]=v[i],mi[i][0]=i; 57 for(j=0;fa[i][j]&&fa[fa[i][j]][j];j++){ 58 fa[i][j+1]=fa[fa[i][j]][j]; 59 if(mn[i][j]<mn[fa[i][j]][j]) mn[i][j+1]=mn[i][j],mi[i][j+1]=mi[i][j]; 60 else mn[i][j+1]=mn[fa[i][j]][j],mi[i][j+1]=mi[fa[i][j]][j]; 61 } 62 } 63 for(i=2;i<=N+1;i++){ 64 Node p; 65 p.x=i,p.l=dep[i]-L,p.r=dep[i]-R-1; 66 // printf("%d %d %d\n",p.x,p.l,p.r); 67 if(p.l<=0) continue; 68 p.v=getrmq(p.x,p.l,p.r,p.m); 69 q.push(p); 70 } 71 ll ans=0; 72 for(i=1;i<=M;i++){ 73 Node p=q.top();q.pop(); 74 ans+=p.v; 75 if(p.m<p.l){ 76 Node p1; 77 p1.x=p.x,p1.l=p.l,p1.r=p.m; 78 p1.v=getrmq(p1.x,p1.l,p1.r,p1.m); 79 q.push(p1); 80 }if(p.r<p.m-1){ 81 Node p2; 82 p2.x=p.x,p2.l=p.m-1,p2.r=p.r; 83 p2.v=getrmq(p2.x,p2.l,p2.r,p2.m); 84 q.push(p2); 85 } 86 } 87 printf("%lld\n",ans); 88 return 0; 89 }