萌新妹子D可AC的假做法求hack
赛时:队友提了一嘴三分,噼里啪啦敲出代码居然A了,求hack或证明正确性
考虑分治,求出一个区间内选i场比赛的最大值,合并两个区间的时候我们猜测其是一个单峰函数,直接三分,莫名其妙就A了
#include <bits/stdc++.h> #define rep(a,b,c) for(int a=(b);a<=(c);a++) #define vi vector<int> #define pb push_back #define vld vector<long double> #define ld long double using namespace std; template<class T>inline void read(T &x) { T f=1; x=0; char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} x*=f; } const int N=1e5; const ld eps=1e-12; ld pw[N+5],k,k1,r0,p[N+5]; int n,m; inline vld cdq(int l,int r) { if(l==r) { vld tmp; tmp.pb(0.0); tmp.pb(k*p[l]); return tmp; } int mid=((l+r)>>1); vld L=cdq(l,mid),R=cdq(mid+1,r); vld ans; ans.pb(0); rep(i,1,r-l+1) { int LL=max(0,i-(r-mid)),RR=min(i,mid-l+1),lmid,rmid; while((RR-LL)>10) { lmid=LL+((RR-LL+1)/3); rmid=RR-((RR-LL+1)/3); ld lv=R[i-lmid]+L[lmid]*pw[i-lmid]; ld rv=R[i-rmid]+L[rmid]*pw[i-rmid]; if((lv-rv)<eps) LL=lmid; else RR=rmid; } ld Max=0.0; rep(j,LL,RR) { ld V=R[i-j]+L[j]*pw[i-j]; if((V-Max)>eps) Max=V; } ans.pb(Max); } return ans; } inline void solve() { read(n); read(m); scanf("%Lf %Lf",&k,&r0); k1=(1.0-k); rep(i,1,n) scanf("%Lf",&p[i]); pw[0]=1.0; rep(i,1,n) pw[i]=pw[i-1]*k1; rep(i,1,n-m) r0*=k1; vld ans=cdq(1,n); ld Ans=0.0; rep(i,n-m,n) { ld nans=ans[i]+r0; if((nans-Ans)>eps) Ans=nans; r0*=k1; } printf("%.12Lf\n",Ans); } int main() { int T; read(T); while(T--) solve(); }