2023 CCPC Online vp补题-D
Ft=∑s=0n−1fse−2πistn=∑s=0n−1fscos(−2πistn)+ifssin(−2πistn)=x+iyx=∑s=0n−1fscos(−2πistn)=∑s!=kfscos(−2πistn)+fkcos(−2πiktn)y同理∣Ft∣2=x2+y2是关于fk的二次函数,进行三分找最小值F_t = \sum_{s=0}^{n-1} f_s\ e^{-2 \pi i s t \over n}\\=\sum_{s=0}^{n-1}f_scos({-2 \pi i s t \over n})+if_ssin({-2 \pi i s t \over n})\\=x+iy\\x=\sum_{s=0}^{n-1}f_scos({-2 \pi i s t \over n})\\=\sum_{s!=k}f_scos({-2 \pi i s t \over n})+f_kcos({-2 \pi i k t \over n})\\y同理\\|F_t|^2={x^2+y^2}是关于f_k的二次函数,进行三分找最小值Ft=∑s=0n−1fs en−2πist=∑s=0n−1fscos(n−2πist)+ifssin(n−2πist)=x+iyx=∑s=0n−1fscos(n−2πist)=∑s!=kfscos(n−2πist)+fkcos(n−2πikt)y同理∣Ft∣2=x2+y2是关于fk的二次函数,进行三分找最小值
const int N=2e3+10,mod=998244353,inf=1e15;
const double pi=acos(-1.0);
double v[N][2],f[N],kcos[N],ksin[N];
int n,k;
double cal(double fk){double res=-1e18;forr(t,0,n-1){//枚举F_i 找最大值double x=fk*kcos[t]+v[t][0],y=fk*ksin[t]+v[t][1];res=max(res,x*x+y*y);}return res;
}
void solve()
{cin>>n>>k;const double idx=-2*pi/(n*1.0);forr(i,0,n-1)cin>>f[i];forr(t,0,n-1){//对每个Fforr(s,0,n-1){//对每个fif(s==k)continue;double rad=idx*(double)s*(double)t;//当前角度v[t][0]+=f[s]*cos(rad);//v是除了k的其他向量的和v[t][1]+=f[s]*sin(rad);}double rad=idx*(double)k*(double)t;kcos[t]=cos(rad),ksin[t]=sin(rad);}double ans=1e18;int l=-4e6,r=4e6;//三分fk的值while (l<r){int lmid=l+(r-l)/3,rmid=r-(r-l)/3;double lc=cal(lmid),rc=cal(rmid);if(lc<=rc)r=rmid-1;else l=lmid+1;ans=min({ans,lc,rc});}/* 另一种三分法for (int mid,l=-4e6,r=4e6;l<=r;){mid=(l+r)/2;double res1=cal(mid),res2=cal(mid+1);if(res1>res2)l=mid+1;elser=mid-1;ans = min({ans,res1,res2});}*/cout<<fixed<<setprecision(15)<<sqrt(ans)<<endl;}