"JSOI 2015" gifts (RMQ + 01 scores planning)

Topic Summary:

In a gift (v [1], v [2] ...... v [n]) selected length to meet the requirements (L <= length <= R) period presents a continuous interval, so that this paragraph presents aesthetics of difference between maximum and minimum values, and the ratio of the maximum length, the maximum ratio is obtained.

Topic analysis:

First with 01 fractional programming, may be provided [M (i, j) -m (i, j)] / (j-i + k) <= ans, finishing to give [M (i, j) -m (i, j )] - ans * (j-i + k) <= 0, then two points can be made ans, focusing on two points in the check () function how to write:

If the subject has no length limit gift selected, in order to make the ratio of the maximum, in this section the selected maximum and minimum aesthetics presents at both ends a certain interval. And because the subject limits the length of the interval, so we should consider two cases:

1: length of the segment is exactly L, is the determination condition at this time: [M (i, j) -m (i, j)] - ans * (l-1 + k) <= 0, the entire pre-treatment st table presents the sequence, then O (n) starting enumerated one by one can be determined.

2: section length is greater than L, while still discussed two cases, i.e., a left end point where two different maximum or minimum. The maximum value (v [j] + j * mid) a - are determined (v [i] -i * mid ) - (v [j] -j * mid) and (v [i] + i * mid) after may be compared with zero.

Code:

#include<iostream>
using namespace std; const double eps=1e-7; int T; int m,n,L,R; int pq1[51015],l1,r1; int pq2[51015],l2,r2; int pq3[51015],l3,r3; int a[51015]; double b[51015]; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d%d%d",&m,&n,&L,&R); for(int i=1;i<=m;i++){ scanf("%d",&a[i]); } l1=r1=l2=r2=0; for(int i=1;i<L;i++){ while(l1<r1&&a[pq1[r1-1]]>=a[i]){ r1--; } while(l2<r2&&a[pq2[r2-1]]<=a[i]){ r2--; } pq1[r1++]=pq2[r2++]=i; } double ans1=-1000; for(int i=L;i<=m;i++){ while(l1<r1&&i-pq1[l1]>=L){ l1++; } while(l2<r2&&i-pq2[l2]>=L){ l2++; } while(l1<r1&&a[pq1[r1-1]]>=a[i]){ r1--; } while(l2<r2&&a[pq2[r2-1]]<=a[i]){ r2--; } pq1[r1++]=pq2[r2++]=i; ans1=max(ans1,1.0*(a[pq2[l2]]-a[pq1[l1]])/(L-1+n)); } double l=0,r=1000; while(r-l>eps){ double mid=(l+r)/2; double cnt=-100000; l3=r3=0; for(int i=1;i<=m;i++){ b[i]=a[i]-i*mid; } for(int i=L+1;i<=m;i++){ while(l3<r3&&i-pq3[l3]>=R){ l3++; } while(l3<r3&&b[pq3[r3-1]]>=b[i-L]){ r3--; } pq3[r3++]=i-L; cnt=max(cnt,b[i]-b[pq3[l3]]); } l3=r3=0; for(int i=1;i<=m;i++){ b[i]=a[i]+i*mid; } for(int i=m-L;i;i--){ while(l3<r3&&pq3[l3]-i>=R){ l3++; } while(l3<r3&&b[pq3[r3-1]]>=b[i+L]){ r3--; } pq3[r3++]=i+L; cnt=max(cnt,b[i]-b[pq3[l3]]); } if(cnt>=mid*n){ l=mid; }else{ r=mid; } } printf("%.4f\n",max(ans1,l)); } return 0; }

 

Guess you like

Origin www.cnblogs.com/051011zzf/p/11273357.html