2019 cattle off more training school fourth C.sequence (segment tree + + prefix and monotonous stack)

Topic Portal

The meaning of problems

Input integer n, given two sequences containing n integers a and b, to find an interval [l, r], so that the value in the minimum sequence interval a × b-series interval and the maximum.

answer

A traversal sequence, maintenance interval monotonically up to find the current value of the stack a [i] is the minimum value of [L [i], R [i]] (i.e., the maximum left and right boundaries);

b prefix sequence before preprocessing and pre_sum, with the segment tree maintenance interval most pre_sum array values; and so the answer is in the a [i] × b sequence [L [i], R [i]] Interval Maximum value, keep seeking the most optimal solution can result.

When a [i] ≥0 When, in the sequence b [L [i], R [i]] and the maximum value of the interval b is a prefix sequence and the second half of the maximum value of the array - the first half of the minimum value, namely:

max ([pre_sum (i), pre_sum (R [i])]) -min ([pre_sum (L [i] -1), pre_sum (i-1)]);

When a [i] <0 when, in the sequence b [L [i], R [i]] and the maximum value of the interval b is a prefix sequence and the second half of the minimum value of the array - the first half of the maximum value, namely:

min ([pre_sum (i), pre_sum (R [i])]) -max ([pre_sum (L [i] -1), pre_sum (i-1)]);

The time complexity of O (nlogn).

Code

  1 /*2442ms*/
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 typedef long long ll;
  5 const int maxn=3e6+5;
  6 const ll inf=0x3f3f3f3f3f3f3f3fLL;
  7 ll a[maxn],b[maxn],pre_sum[maxn],L[maxn],R[maxn],sta[maxn];
  8 struct node
  9 {
 10     int l,r;//区间[l,r]
 11     ll mx;//区间最大值
 12     ll mn;// interval minimum value 
13 is } Tree [MAXN << 2 ]; // must be open to more than four times the space 
14  void a pushup ( int index)
 15  {
 16      Tree [index] = max .mx (Tree [index << . 1 ] .mx, Tree [index << . 1 | . 1 ] .mx);
 . 17      Tree [index] = min .mn (Tree [index << . 1 ] .mn, Tree [index << . 1 | . 1 ] .mn) ;
 18 is  }
 . 19  void Build ( int L, int R & lt, int index)
 20 is  {
 21 is     tree[index].l=l;
 22     tree[index].r=r;
 23     if(l==r){
 24         tree[index].mn=tree[index].mx=pre_sum[l];
 25         return;
 26     }
 27     int mid=(l+r)>>1;
 28     build(l,mid,index<<1);
 29     build(mid+1,r,index<<1|1);
 30     pushup(index);
 31 }
 32 ll queryMIN(int l,int r,int index)
 33 {
 34     if(l<=tree[index].l&&r>=tree[index].r)
 35         return tree[index].mn;
 36     int mid=(tree[index].l+tree[index].r)>>1;
 37     ll Min=inf;
 38     if(l<=mid)
 39         Min=min(queryMIN(l,r,index<<1),Min);
 40     if(r>mid)
 41         Min=min(queryMIN(l,r,index<<1|1),Min);
 42     return Min;
 43 }
 44 ll queryMAX(int l,int r,int index)
 45 {
 46     if(l<=tree[index].l&&r>=tree[index].r)
 47         return tree[index].mx;
 48     int mid=(tree[index].l+tree[index].r)>>1;
 49     ll Max=-inf;
 50     if(l<=mid)
 51         Max = max(queryMAX(l,r,index<<1),Max);
 52     if(r>mid)
 53         Max = max(queryMAX(l,r,index<<1|1),Max);
 54     return Max;
 55 }
 56 int main()
 57 {
 58     int n;
 59     while(~scanf("%d",&n))
 60     {
 61         for(int i=1;i<=n;i++)
 62             scanf("%lld",&a[i]);
 63         for(int i=1;i<=n;i++){
 64             scanf("%lld" , & B [I]);
 65              pre_sum [I] = pre_sum [I- . 1 ] + b [I]; // find a prefix and a sequence b 
66          }
 67          Build ( 0 , n-, . 1 );
 68          / * monotone stack find the left point L [I] * / 
69          int Top = 0 ;
 70          for ( int I = . 1 ; I <= n-; I ++ ) {
 71 is              the while (Top && A [I] <= A [STA [Top]])
 72                  top-- ;
 73 is              L [I] = (Top == 0 )? . 1: STA [Top] + . 1 ;
 74              STA [Top ++] = I;
 75          }
 76           / * monotonic stack find the right end R & lt [I] * / 
77          Top = 0 ;
 78          for ( int I = n-; I> = . 1 ; i-- ) {
 79              the while (Top && A [I] <= A [STA [Top]])
 80                  top-- ;
 81              R & lt [I] = (Top == 0 ) n-: STA [Top] -? . 1 ;
 82              STA [Top ++] = I;
 83          }
 84          
85         ll years = - inf;
86          for ( int i = 1 ; i <= n; i ++ ) {
 87              'll cnt = 0 ;
88              if (a [i]> 0 ) {
 89                  cnt = (queryMAX (and R [i], 1 ) -queryMIN (L [i] - 1 , i- 1 , 1 )) * a [i];
90              }
 91              else  if (a [i] < 0 ) {
 92                  cnt = (queryMIN (and R [i], 1 ) -queryMAX (L [i] - 1 , i- 1, 1 )) * a [i];
93              }
 94              else  if (a [i] == 0 )
 95                  cnt = 0 ;
96              if (cnt> years) years = cnt;
97          }
 98          printf ( " % lld \ n " , year);
99      }
 100      return  0 ;
101  }
 102  
103  / * 
104  7
 105  -519 9794 1664 -295 8189 3471 1104
 106  -1796 -3137 7098 -3333 4683 -3968 467 3
107 11811072
108 */
109 /*
110 18
111 -273 7169 -8145 -6664 -2970 698 8701 -6791 459 -5678 -846 8072 6384 5051 -3606 -4737 -9928 6815
112 1609 -8810 9205 -9129 -1919 -116 -6752 385 4347 614 6261 4399 -8961 1022 -1360 -5074 7825 -122
113 142708545
114 */
View Code

 

Guess you like

Origin www.cnblogs.com/HOLLAY/p/11374517.html