社区讨论

求助卡精度

P4027[NOI2007] 货币兑换参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lo93i4h7
此快照首次捕获于
2023/10/28 04:58
2 年前
此快照最后确认于
2023/10/28 04:58
2 年前
查看原帖
WA 6
CPP

#include<bits/stdc++.h>
#define mset(a,b) memset((a),(b),sizeof((a)))
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define dec(i,l,r) for(int i=(r);i>=(l);i--)
#define inc(a,b) (((a)+(b))>=mod?(a)+(b)-mod:(a)+(b))
#define sub(a,b) (((a)-(b))<0?(a)-(b)+mod:(a)-(b))
#define mul(a,b) 1ll*(a)*(b)%mod
#define sgn(a) (((a)&1)?(mod-1):1)
#define cmax(a,b) (((a)<(b))?(a=b):(a))
#define cmin(a,b) (((a)>(b))?(a=b):(a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define N 100010
#define M number
using namespace std;

typedef double dd;
typedef long double ld;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
//#define int long long
typedef pair<int,int> P;
typedef vector<int> vi;

const int INF=0x3f3f3f3f;
const ld eps=1e-15;
const int mod=998244353;

template<typename T> inline void read(T &x) {
    x=0; int f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c == '-') f=-f;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    x*=f;
}

int n,m,t;
ld f[N],x[N],y[N],a[N],b[N],ra[N];
pair<ld,ld> p[N],st[N];
typedef pair<ld,ld> PP;

inline ld operator ^ (const pair<ld,ld> &A,const pair<ld,ld> &B){
    return B.se*A.fi-B.fi*A.se;
}
inline pair<ld,ld> operator - (const PP &A,const PP &B){
    return mp(A.fi-B.fi,A.se-B.se);
}
inline ld calc(PP A,PP B){
    if(A.fi<B.fi) swap(A,B);
    if(fabs(B.fi-A.fi)<eps) {if(B.se<A.se) return 1e18;else return -1e18;}
    return (B.se-A.se)/(B.fi-A.fi);
}

inline int bi(ld k,int l,int r){
    while(l<r){
        int mid=(l+r+1)>>1;
        if(mid==1||calc(st[mid],st[mid-1])>k) l=mid;
        else r=mid-1; 
    }
    return l;
}
inline void Solve(int l,int r){
    // printf("l=%d r=%d\n",l,r);
    if(l==r){
        f[l]=max(f[l],f[l-1]);
        // printf("f[%d]=%Lf\n",l,f[l]);
        return;
    }
    int mid=(l+r)>>1;Solve(l,mid);
    rep(i,l,mid) x[i]=f[i]*ra[i]/(ra[i]*a[i]+b[i]);
    rep(i,l,mid) y[i]=f[i]/(ra[i]*a[i]+b[i]);
    rep(i,l,mid) p[i-l+1]=mp(x[i],y[i]);
    // rep(i,l,mid) printf("x[%d]=%Lf y[%d]=%Lf\n",i,x[i],i,y[i]);
    sort(p+1,p+(mid-l+1)+1);
    // printf("l=%d r=%d mid=%d\n",l,r,mid);
    if(mid-l+1==1){
        // printf("x[%d]=%Lf y[%d]=%Lf\n",mid,x[mid],mid,y[mid]);
        rep(i,mid+1,r) f[i]=max(f[i],x[mid]*a[i]+y[mid]*b[i]);
    }
    else{
        t=0;
        st[++t]=p[1];st[++t]=p[2];
        rep(i,3,(mid-l+1)){
            while(t>=2&&((p[i]-st[t])^(st[t-1]-st[t]))>0) t--;
            st[++t]=p[i];
            // printf("t=%d\n",t);
            // rep(i,1,t) printf("%Lf %Lf\n",st[i].fi,st[i].se);
        }
        // printf("t=%d\n",t);
        // rep(i,1,t) printf("%Lf %Lf\n",st[i].fi,st[i].se);
        rep(i,mid+1,r){
            ld k=-a[i]/b[i];int now=bi(k,1,t);
            // printf("i=%d now=%d\n",i,now);
            // printf("st[now].fi=%Lf st[now].se=%Lf\n",st[now].fi,st[now].se);
            // printf("i=%d %Lf %Lf\n",i,st[now].fi,st[now].se);
            f[i]=max(f[i],st[now].fi*a[i]+st[now].se*b[i]);
        }
    }
    Solve(mid+1,r);
}

int main(){
    // assert(freopen("my.in","r",stdin));
    // assert(freopen("my.out","w",stdout));
    read(n);read(m);
    rep(i,1,n){
        scanf("%Lf%Lf%Lf",&a[i],&b[i],&ra[i]);
    }
    f[1]=m;Solve(1,n);
    printf("%0.3Lf\n",f[n]);
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...