Function: convex hull, monotone stack, the question is intended conversion, singlet third function, processed offline

Difficult ah ah ah! ! !

bzoj5380 the original title, the title should be sticky surface.

Conversion problem:

A matrix with n columns 1e9 row, the same numbers are written on each column Ai.

You start each step can take a step to the left or to the left, and finally went to the first line from the position (x, y).

Requirements on the total weight of the path is minimized.

First question is intended to convert let me hang up. . .

Then the solution to a problem in an obvious conclusion I hung up for a while: the optimal decision is to walk a few steps on the left, go straight on up.

It proved relatively simple. Because if you go up a few steps and then left to go on, then we might as well go on the left, otherwise it is not optimal decision.

So you can enumerate turn position. (27% violence)

 1 #include<cstdio>
 2 #include<iostream>
 3 #define int long long
 4 int n,q,a[500005],sum[500005],x,y,ans;
 5 main(){
 6     scanf("%lld",&n);
 7     for(int i=1;i<=n;++i)scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];
 8     scanf("%lld",&q);
 9     while(q--){
10         scanf("%lld%lld",&x,&y);
11         ans=x*a[y];
12         for(int i=1;i<y;++i)if(y-i<x)ans=std::min(ans,sum[y]-sum[i]+a[i]*(x+i-y));
13         printf("%lld\n",ans);
14     }
15 }
View Code

It can be found, for the starting point (x, i), which in turn j-th column, the cost is a linear function of x as the independent variable.

We also put all the straight lines drawn, then a straight line when they take the lowest point of x can be.

How to maintain these lines do?

First it is proved, for any x in a column, which may be the optimal solution must straight line A is incremented.

Then we can ask all off, followed by processing each column is like, always maintain

Sensual understand the words that you will find the sideways move forward on a smaller A and then further to go, if you cross a smaller A walk on a larger A Beyond it is certainly not excellent. . .

Concrete proof, then no time to write it. . . Recommended Blog: https://blog.csdn.net/Rose_max/article/details/82250809

In this case the larger A popped out like a bomb when we maintain a monotonous stack, the stack by a straight line A is incremented by adding a new line.

But this alone is not enough, and not all the useless bomb straight away.

Consider the stack of two lines:

Stack: y = x

Penultimate: y = 0.5x + 0.5

To join the linear now: y = 2x-4

This three lines meet A monotonically increasing, it can be added directly to the straight line?

Not draw a straight line on the three coordinate system, we will never find a minimum value on the straight line y = x

At the point (3,2) after the minimum y = 0.5x + 0.5, formerly y = 2x-4

This is to maintain the convex hull of the matter. . . We determined the two straight lines is determined by the straight line and the newly added stack point of intersection with the straight line there is no top of the stack.

If the intersection of the horizontal axis linear stack larger, then straight on top of the stack is not used.

After promptly popped we have the convex hull, now remaining question is how to find it known x value in the convex hull.

It can be shown to both sides of the stack sweeps from the best piece of straight lines, costs are monotonically increasing.

So the cost on the slope of the valley is a single function. Where you can find three-point straight line.

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 #define int long long
 5 struct qs{int x,y,id;friend bool operator<(qs a,qs b){return a.y<b.y;}}q[500005];
 6 int n,a[500005],Q,b[500005],sum[500005],ans[500005],sta[500005];
 7 int cal(int p,int x){return a[p]*x+b[p];}
 8 double jiao_dian(int p,int q){return (1.0*b[q]-b[p])/(a[p]-a[q]);}
 9 signed main(){
10     scanf("%lld",&n);
11     for(int i=1;i<=n;++i)scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];
12     scanf("%lld",&Q);
13     for(int= I . 1 ; I <= Q; I ++) Scanf ( " %% LLD LLD " , & Q [I] .x, & Q [I] .y), Q [I] .id = I;
 14      Sort (Q + . 1 , Q + . 1 + Q);
 15      for ( int I = . 1 , Alq = . 1 , Top = 0 ; I <= n-; ++ I) {
 16          B [I] = - SUM [I- . 1 ] + A [ I] * (I- . 1 ); // meaning: sum of the set value when calculating the difference made, then go one step i-1 (could go ahead, but here the choice going up) 
. 17          the while (Top && A [STA [Top]]> A = [I]) top--; // the stack slope must not preferable incremented or 
18 is          the while (Top> . 1jiao_dian && (the STA [TOP- 1 ], i) <jiao_dian (the STA [Top], i)) top--; // If the line is not the most top of the stack and the decision on any x then pop out 
19          the STA [ Top ++] = I;
 20 is          the while (Alq <&& Q = Q [Alq] .y == I) {
 21 is              int X-Q = [Alq] .x, the Y = Q [Alq] .y, L = lower_bound (STA + . 1 , STA + Top + . 1 , the Y-X-+ . 1 ) C-Sta, R & lt TOP- = . 1 ; // find feasible stack section 
22 is              the while (L <R & lt) IF (CAL (STA [L + R & lt >> . 1 ], the XY )> CAL (STA [(L + R & lt >> . 1 ) + . 1 ], the XY)) L = (L + R & lt >> . 1 ) + . 1 ; the else R & lt = L + R & lt >>1 ; // third single valley, XY is the least number of steps to go, and the remaining number of steps in which b 
23 is              the while (L <CAL Top && (STA [L], XY)> = CAL (STA [L + 1 ] , the XY)) L ++; // trailing until the optimal solution 
24              ANS [Q [Alq] .id] = CAL (STA [L], the XY) + SUM [I]; Alq ++; // to add obliquely down charges 
25          }
 26 is      }
 27      for ( int I = . 1 ; I <= Q; ++ I) the printf ( " % LLD \ n- " , ANS [I]);
 28 }
View Code

 

Guess you like

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