NOI2004 rainfall

\(Problem Link\)

Adaptive Simpson, an accuracy of the card. . .

cancer.

/*
@Date    : 2019-07-30 07:58:53
@Author  : Adscn ([email protected])
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
IL int getint()
{
    RG int xi=0;
    RG char ch=gc;
    bool f=0;
    while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
    while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
    return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
    if(k<0)k=-k,putchar('-');
    if(k>=10)pi(k/10,0);
    putchar(k%10+'0');
    if(ch)putchar(ch);
}
typedef long double db;
const db eps = 1e-7;
int n,m,w,T,V;
struct line{
    db x,y,len,k,L,R;
}L[5010];
inline int dcmp(db a){
    if(fabs(a)<(long double)eps)return 0;
    return a<0?-1:1;
}
struct inter{
    db l,r;
    bool operator <(const inter & b)const{
        if(dcmp(l-b.l)==0)return dcmp(r-b.r)<0;
        return dcmp(l-b.l)<0;
    }
}c[307];
inline db f(db x)
{
    db s=0;int p=0;
    for(int i=1;i<=m;++i)
        if(dcmp(L[i].L-x)<0&&dcmp(x-L[i].R)<0)
        {
            if(fabs(L[i].k)>eps)
            {
                db t1=(x-L[i].x)/L[i].k+L[i].y,
                t2=(x-L[i].x-L[i].len)/L[i].k+L[i].y;
                c[++p].l=max(L[i].y,min(t1,t2));
                c[p].r=min(L[i].y+(L[i].R-L[i].L-L[i].len)/fabs(L[i].k),max(t1,t2));
            }
            else return T;
        }
    if(!p)return 0;
    sort(c+1,c+p+1);
    db l=c[1].l,r=c[1].r;
    for (int i=2;i<=p;++i)
        if (dcmp(c[i].l-r)>0)s+=r-l,l=c[i].l,r=c[i].r;
        else r = max(c[i].r,r);
    s += r-l;
    return s;
}
inline db simpson(db l,db r){db mid=(l+r)/2;return (f(l)+4*f(mid)+f(r))*(r-l)/6;}
db autosimpson(db l,db r,db sum)
{
    db mid=(l+r)/2;
    db lsum=simpson(l,mid),rsum=simpson(mid,r);
    if(fabs(lsum+rsum-sum)<eps)return lsum+rsum;
    return autosimpson(l,mid,lsum)+autosimpson(mid,r,rsum);
}
void check(db x,db y,db len,db v,db t)//x初始位置
{
    db l=min(x,x+t*v),r=max(x+len,x+len+t*v);
    L[++m].L=l,L[m].R=r,L[m].k=v;
    L[m].x=x,L[m].y=y,L[m].len=len;
    if(r>w)
    {
        L[m].R=w;
        check(w-len,y+(w-len-x)/v,len,-v,t-(w-len-x)/v);
    }
    else if(l<-eps)
        {
            L[m].L=0;
            check(0,y-x/v,len,-v,t+x/v);
        }
}
int main(void)
{
    n=gi,w=gi,T=gi,V=gi;
    for(int i=1;i<=n;++i)
    {
        int x=gi,l=gi,v=gi;
        if(v&&(x||l!=w))check(x,0,l,v,T);
        else L[++m].k=0,L[m].L=x,L[m].R=x+l;
    }
    printf("%.2Lf",fabs((T*w-autosimpson(0,w,simpson(0,w)))*V-0.0004));
    return 0;
}

Guess you like

Origin www.cnblogs.com/LLCSBlog/p/11269180.html