1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| #include<bits/stdc++.h> using namespace std; typedef double db; #define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i) #define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
char IO; template <class T=int> T rd(){ T s=0; int f=0; while(!isdigit(IO=getchar())) if(IO=='-') f=1; do s=(s<<1)+(s<<3)+(IO^'0'); while(isdigit(IO=getchar())); return f?-s:s; }
const int N=3e5+10;
int n,D; struct City{ int k,x,h; } C[N];
struct Lightpair{ int x,y; Lightpair(const int &_x=0,const int &_y=0) : x(_x),y(_y) { } db Left(){ return C[y].x+1.0*(C[y].x-C[x].x)/(C[x].h-C[y].h)*C[y].h; } } stk[N]; int top; void Cover(Lightpair &x,int y){ if(Lightpair(x.x,y).Left()>x.Left()) x.y=y; } db s[2][N];
int main(){ n=rd(),D=rd(); rep(i,1,n) C[i].k=rd(),C[i].x=rd(),C[i].h=rd(); C[n+1].x=D; rep(k,0,1) { rep(i,0,n) { while(top && C[stk[top].x].h<=C[i].h) top--; if(top) { Cover(stk[top],i); while(top>1){ Cover(stk[top-1],i); if(stk[top-1].Left()>stk[top].Left()) break; top--; } } if(C[i].k) stk[++top]=i,s[k][i]=C[i].x; else if(top) s[k][i]=min(stk[top].Left(),(db)C[i+1].x); else s[k][i]=C[i+1].x; } if(!k) { reverse(C+1,C+n+1),top=0; rep(i,1,n) C[i].x=D-C[i].x; } else { reverse(s[k],s[k]+n+1); rep(i,0,n) s[k][i]=D-s[k][i]; } } db ans=D; rep(i,0,n) if(s[0][i]>s[1][i]) ans-=s[0][i]-s[1][i]; printf("%.3lf\n",ans); }
|