RT,代码数组开到 1005 会 RE#9,开到 100005 会 WA#3,不知道为什么QAQ。(思路大概是分段三分)
//author:望远星
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define sml(x,y) (x=cmp(x,y)?x:y)
#define big(x,y) (x=max(x,y))
#define ll long long
#define ull unsigned long long
#define db long double
#define fo(i,x,y) for(int i=x;i<=y;++i)
#define go(i,x,y) for(int i=x;i>=y;--i)
using namespace std;
ull seed=chrono::system_clock::now().time_since_epoch().count();
mt19937 rnd(seed);
inline int rm(int x,int y){return rnd()%(y-x+1)+x;}
inline int read(){int x=0,f=1;unsigned char ch=getchar()-48;while(ch>9){if(ch==253)f=-1;ch=getchar()-48;}while(ch<=9){x=x*10+ch;ch=getchar()-48;}return x*f;}
inline void out(db *a,int l,int r){fo(i,l,r) cout<<*(a+i)<<' ';puts("");}
const int N=100005;
const db eps=1e-10;
struct Point{
db x,y;
Point(){}
Point(db a,db b){x=a,y=b;}
double operator *(const Point &a)const{return x*a.y-y*a.x;}
}P[N],s[N];
typedef Point vec;
vec operator+(const vec &a,const vec &b){return vec(a.x+b.x,a.y+b.y);}
vec operator-(const vec &a,const vec &b){return vec(a.x-b.x,a.y-b.y);}
vec operator*(const vec &a,const db k){return vec(a.x*k,a.y*k);}
db Dis(const Point &a,const Point &b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int n,m;
db C,dis[N],a[N],b[N],d[N];
bool cmp(db x,db y){//x是否小于等于y
if(fabs(x-y)>=eps) return x<y;
return 1;
}
bool cmp2(db x,db y){
if(fabs(x-y)>=eps) return x<y;
return 0;
}
db calc(db qwq){
//printf("calc(%.12Lf)\n",qwq);
int id=0;
a[1]=qwq;fo(i,2,m) a[i]=a[i-1]+C;
fo(i,1,m){
while(id<=n&&cmp(d[id+1],a[i])){
++id;
//printf("%d %d\n",i,id);
if(id>n){
cout<<id,puts("?");
printf("%d:%.12Lf,%.12Lf\n",i,a[i],d[n+1]);
}
else{
Point x=P[id],y=id==n?P[1]:P[id+1];
s[i]=x+(y-x)*((a[i]-d[id])/dis[id]);
}
}
double ans=0;
for(int i=1;i<m;i++) ans+=s[i]*s[i+1];
ans+=s[m]*s[1];
// fo(i,1,m-2) ans+=(s[i+1]-s[1])*(s[i+2]-s[1]);
return abs(ans/2);
}
void init(){
db mx=0.0;
int pos=0;
fo(i,1,n) P[i].x=read(),P[i].y=read();reverse(P+2,P+1+n);
dis[n]=C=Dis(P[1],P[n]);fo(i,2,n) dis[i-1]=Dis(P[i-1],P[i]),C+=dis[i-1];
fo(i,1,n) if(dis[i]>mx) mx=dis[i],pos=i;
Point tmp[N];
fo(i,1,n) tmp[i]=P[i];
//cout<<"pos="<<pos<<'\n';
fo(i,pos,n) P[i-pos+1]=tmp[i];
fo(i,1,pos-1) P[i+pos]=tmp[i];
//fo(i,1,n) printf("(%f,%f)\n",P[i].x,P[i].y);
dis[n]=Dis(P[1],P[n]);fo(i,2,n) dis[i-1]=Dis(P[i-1],P[i]);
}
signed main(){
cin>>n>>m;
//逆时针->顺时针
init();
C/=m;
//顺时针展开成一个 n+1 个点的数轴
//d 为顶点在数轴上的位置,a 为初始时的 m 个点,b 为决策段拐点
fo(i,2,m) a[i]=a[i-1]+C;
fo(i,1,n+1){
d[i]=d[i-1]+dis[i-1];
//b[i]=a[lower_bound(a+1,a+1+m,d[i])-a-1];
b[i]=d[i]-floor(d[i]/C)*C;
}b[n+2]=C-2*eps;
//cout<<"a:";out(a,1,m);cout<<"d:";out(d,1,n+1);cout<<"b:";out(b,1,n+2);
//fo(i,1,3) b[n+2+i]=i;
sort(b+1,b+2+n,cmp2);
db ans=4e10;
fo(i,1,n+1){//对 [ b[i],b[i+1] ] 三分
//printf("%f,%f\n",b[i],b[i+1]);
db l=b[i],r=b[i+1];
if(cmp(C,r)) r=C;
if(cmp(r,l)) l=r;
sml(ans,calc(l));sml(ans,calc(r));
int T=60;
while(r-l>=eps){
db lmid=l+(r-l)/3,rmid=l+(r-l)*2/3;
db x=calc(lmid),y=calc(rmid);
if(cmp(y,x)) sml(ans,y),l=lmid;
else sml(ans,x),r=rmid;
}
printf("%.10Lf",ans);
return 0;
}
/*
-------------------------------------------------
*/