Lost My Music: multiplier implements monotone persistence stack maintenance convex hull

Ancestors topic is required in each node in the tree (ci-cj) / (dj-di) minimum.

So it is (ci-cj) / (di-dj) of the maximum.

For each point, it's (ci, di) are two-dimensional coordinate system of a point

Minimum slope requirement is that all points ancestor nodes of the current node connection

Relatively easy to think monotonous stack optimization, the same as the slope of the optimization dp

But the key is this question in the trees, there will be a lot of trouble operation.

When the search to one son might be playing a lot of the stack, and the process of backtracking is required to add them back.

If violence implemented, it would degenerate in Dandelion map for the n- 2 .

Consider Optimization: The key now lies in how quickly maintenance in the case of an element may be popping / restore many times?

Consider doubled. st [i] [j] represents the representatives from the elements j jump forward in the stack 2 i who represents the element after element yes. We could have opened a log stack level for each node.

Then only we need to explore the stack connected to the father of a position which put certain elements just fine. Monotone stack monotone course, it is possible to skip multiplication.

So to stack the parent node In fact, we do not change it.

Because there may be an element of it popped back end of the element may not be unique, but then the front of the stack to determine the time element would be uniquely determined.

Monotonous top of the stack is the optimal decision point.

Study the code, it is well understood.

 1 #include<cstdio>
 2 int st[22][500005],fir[500005],l[500005],to[500005],cnt,n,c[500005];
 3 int q[500005],fa[500005],dep[500005];long double ans[500005];
 4 void link(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
 5 long double calc(int x,int y){return 1.0L*(c[x]-c[y])/(dep[y]-dep[x]);}
 6 void pop_push(int p){
 7     int x=fa[p];
 8     for(int i=20;i>=0;--i)if(st[0][st[i][x]]&&calc(st[0][st[i][x]],st[i][x])<calc(st[i][x],p))x=st[0][st[i][x]];
 9     if(st[0][x]&&calc(st[0][x],x)<calc(x,p))x=st[0][x];
10     st[0][p]=x;ans[p]=calc(st[0][p],p);
11     for(int i=1;i<=20;++i)st[i][p]=st[i-1][st[i-1][p]];
12 }
13 int main(){
14     scanf("%d",&n);q[1]=1;
15     for(int i=1;i<=n;++i)scanf("%d",&c[i]);
16     for(int i=2;i<=n;++i)scanf("%d",&fa[i]),link(fa[i],i);
17     for(int h=1,t=1;h<=t;++h){
18         dep[q[h]]=dep[fa[q[h]]]+1;pop_push(q[h]);
19         for(int i=fir[q[h]];i;i=l[i])q[++t]=to[i];
20     }
21     for(int i=2;i<=n;++i)printf("%.8Lf\n",ans[i]);
22 }
View Code

 

Guess you like

Origin www.cnblogs.com/hzoi-DeepinC/p/11371320.html