是这样的
是这样的,我的 \(O(128n\log n)\) 做法没有跑过 \(O(128n\log^2 n)\) 做法。
zr day5 t2
场切了,又没场切。
首先考虑圆上两点距离怎么求。
如果知道圆上两点坐标,直接欧几里得公式 \(dis=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}\)。
但是并不知道,考虑扔到坐标系上,这就是一个单位圆,充分发挥人类智慧,利用勾股定理求出每个点的坐标,手动算出距离即可。可以发现,两点之间的距离只与中间隔着几个点有关。
不难发现,将一些点移到坐标轴上,然后对于不在坐标轴上的点,横纵坐标的绝对值都为 \(\dfrac{\sqrt{2}}{2}\)。
二分速度 \(v\)。
考虑 dp,\(dp_{i,j}\) 表示获得 \(i\) 分且落在 \(j\) 位置上的最小时间(实数),分类讨论转移,时间复杂度 \(O(128n\log n)\)。
题解复杂度 \(O(128n+16n\log n)\),怎么会是呢?
悬赏卡常。
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
//#define double long double
//#pragma GCC optimize(1)
//#pragma GCC optimize(2)
#pragma GCC optimize(3)
//using long double=double;
//#define file(...) freopen("##__VA_ARGS__.in","r",stdin);freopen("##__VA_ARGS__.out","w",stdout)
//#define outfile(...) freopen("##__VA_ARGS__.out","w",stdout)
//#define infile(...) freopen("##__VA_ARGS__.in","r",stdin);
//#define datafile(...) freopen("##__VA_ARGS__.in","w",stdout)
#define debug(...) fprintf(stderr,##__VA_ARGS__)
//#define printf(...) fprintf(stdout,##__VA_ARGS)
template<typename T,typename I>
#define heap(T) std::priority_queue<T>
#define umap(T,I) std::unordered_map<T,I>
#define pii(T,I) std::pair<T,I>
#define map(T,I) std::map<T,I>
#define vector(T) std::vector<T>
#define stack(T) std::stack<T>
using ll=long long;
using i128=__int128;
using ull=unsigned long long;
template<typename T>
inline void read(T &x){
x=0;
char c=getchar();
int f=1;
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(int)(c-'0'),c=getchar();
x*=f;
}
template<typename T,typename I>
inline void chkmin(T &a,I b){
a=std::min(a,b);
}
template<typename T,typename I>
void chkmax(T &a,I b){
a=std::max(a,b);
}
//随机数部分
std::mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
template<typename T>
int getgen(T L,T R){
return rnd()%(R-L+1)+L;
}
const double eps=1e-7,pi=std::acos(-1);
const int inf=1e18,MOD1=998244353,MOD2=1e9+7,MOD3=2147483579,MOD4=19198111;
const __int128 inf128=1e30;
bool Mbe;
stack(char) st;
template<typename T>
void print(T x){
while(st.size()) st.pop();
if(x==0) st.push('0');
if(x<0) putchar('-'),x=-x;
while(x) st.push((char)('0'+x%10)),x/=10;
while(st.size()) putchar(st.top()),st.pop();
}
template<typename T>
void printsp(T x){
print(x);
putchar(' ');
}
template<typename T>
void println(T x){
print(x);
putchar('\n');
}
const int maxn=20010,nxam=10010;
const long double sqrt2=1.41421356237309;
long double dp[maxn][10];//,dis[5]={0,std::sqrt(std::pow(sqrt2/2.0,2)+std::pow(1.0-sqrt2/2.0,2)),sqrt2,std::sqrt(std::pow(sqrt2/2.0,2)+std::pow(1.0+sqrt2/2.0,2)),2.0};
long double dis[5]={0,0.765366864730,1.414213562373,1.847758065023,2.0};
int t[maxn],x[maxn],n,k;
//long double mi[maxn][nxam][10];
long double getdis(int x,int y){
if(x>y) std::swap(x,y);
int dist=y-x;
if(dist>4) dist=8-dist;
return dis[dist];
}
long double time(long double dis,long double v){
if(v==0) return 1e9;
return dis/v;
}
const int maxt=1e6+11;
long double mi[maxt][10];
long double in[maxt][10];
long double go[10][10];
void preinit(){
for(int i=0;i<=(int)1e6+10;i++)
for(int j=1;j<=8;j++) in[i][j]=mi[i][j]=1e9;
for(int i=1;i<=n;i++) in[t[i]][x[i]]=t[i]*1.0;
for(int j=1;j<=8;j++){
for(int i=(int)1e6+9;i>=0;i--) mi[i][j]=mi[i+1][j],chkmin(mi[i][j],in[i][j]);
}
return ;
}
long double y,z,u,d;
int into=0;
struct Info{
int t,x;
}a[nxam];
bool comp_t(Info s1,Info s2){
return s1.t<s2.t;
}
bool Acheck(long double p){
// for(int i=1;i<=n;i++) a[i].t=t[i],a[i].x=x[i];
// std::sort(a+1,a+n+1,comp_t);
long double T=a[1].t-0.2;
int pos=a[1].x;
for(int i=2;i<=n;i++){
T=T+time(getdis(pos,a[i].x),p);
if(T<a[i].t-0.2) T=a[i].t-0.2;
if(T-a[i].t>0.2) return 0;
pos=a[i].x;
}
return 1;
}
int lim;
bool check(long double p){
// if(2.0-p<=1e-5) return 1;
// if(p>0.5) return 1;
// if(p<0.5) return 0;
// for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) debug("dis %lld -> %lld : %.7Lf\n",i,j,time(getdis(i,j),p));
//dp[i][j]:i j
for(int i=1;i<=8;i++) dp[0][i]=0.0;
for(int i=1;i<=8;i++) for(int j=1;j<=8;j++) go[i][j]=time(getdis(i,j),p);
// int lim=std::min(n*2,k+1);
for(register int i=1;i<=lim;i++){
for(register int j=1;j<=8;j++){
dp[i][j]=1e9;
//dp[i][j]
// debug("ok\n");
for(int k=1;k<=8;k++){
// into++;
long double x=dp[i-1][k];
if(x>1e7) continue;
y=go[j][k];
z=x+y;
if(j==k&&i!=1) z+=1.0;
d=(std::floor(z)),u=(std::ceil(z));
// if(j==k) d+=1.0;
// debug("i=%lld j=%lld k=%lld d=%.7Lf u=%.7Lf z=%.7Lf\n",i,j,k,d,u,z);
if(z-d>0.2&&z-d<=0.4){
if(mi[(int)d][j]==d) chkmin(dp[i][j],z);
else chkmin(dp[i][j],mi[(int)d][j]-0.4);
}
else{
if(mi[(int)d+1][j]==d+1.0) chkmin(dp[i][j],std::max(z,mi[(int)d+1][j]-0.4));
else chkmin(dp[i][j],mi[(int)d+1][j]-0.4);
}
if(u-z>0.2&&u-z<=0.4){
if(mi[(int)u][j]==u) chkmin(dp[i][j],z);
else chkmin(dp[i][j],mi[(int)u+1][j]-0.4);
}
else chkmin(dp[i][j],mi[(int)u+1][j]-0.4);
// debug("dp=%.7Lf\n",dp[i][j]);
}
// debug("first appear i=%lld j=%lld dp=%.7Lf\n",i,j,dp[i][j]);
if(i==1) continue;
// debug("okk\n");
for(int k=1;k<=8;k++){
long double x=dp[i-2][k];
if(x>1e7) continue;
y=go[j][k];
z=x+y;
if(j==k&&i!=2) z+=1.0;
d=(std::floor(z)),u=(std::ceil(z));
// if(j==k) d=d+1.0;
if(z-d<=0.2){
if(mi[(int)d][j]==d) chkmin(dp[i][j],z);
else chkmin(dp[i][j],mi[(int)d][j]-0.2);
}
else{
if(mi[(int)d+1][j]==d+1.0) chkmin(dp[i][j],std::max(z,mi[(int)d+1][j]-0.2));
else chkmin(dp[i][j],mi[(int)d+1][j]-0.2);
}
if(u-z<=0.2){
if(mi[(int)u][j]==u) chkmin(dp[i][j],z);
else chkmin(dp[i][j],mi[(int)u][j]-0.2);
}
else chkmin(dp[i][j],mi[(int)u+1][j]-0.2);
// debug("k=%lld d=%.7Lf u=%.7Lf z=%.7Lf x=%.7Lf y=%.7Lf\n",k,d,u,z,x,y);
}
if(i>=k&&dp[i][j]<1e7) return 1;
// debug("p=%.7Lf i=%lld j=%lld dp=%.7Lf\n",p,i,j,dp[i][j]);
}
}
return 0;;
long double tt=1e9;
for(int i=k;i<=2*n;i++)
for(int j=1;j<=8;j++) if(dp[i][j]<1e9) chkmin(tt,dp[i][j]);//,debug("i=%lld j=%lld %.7Lf\n",i,j,dp[i][j]);
// debug("tt=%.10Lf\n",tt);
return tt<1e7;
}
bool Men;
signed main(){
// freopen("ex_maimai3.in","r",stdin);
// std::ios::sync_with_stdio(false);
// file();
// assert(1);
// debug("%.8lfMB\n",(&Mbe-&Men)/1048576.0);
// for(int i=1;i<=4;i++) debug("%.12Lf\n",dis[i]);
// return 0;
read(n),read(k);
if(k<=2){
printf("0\n");
return 0;
}
lim=std::min(2*n,k+1);
for(int i=1;i<=n;i++) read(t[i]),read(x[i]);
preinit();
long double l=0,r=2.0;
int cnt=0;
for(int i=1;i<=n;i++) a[i].t=t[i],a[i].x=x[i];
if(k==2*n) std::sort(a+1,a+n+1,comp_t);
while(r-l>=eps){
if(k==2*n){
long double mid=(l+r)/2.0;
if(Acheck(mid)) r=mid;
else l=mid;
continue;
}
if(++cnt>=22) break;
long double mid=(l+r)/2.0;
// debug("%.7Lf\n",mid);
if(check(mid)) r=mid;
else l=mid;
}
printf("%.10Lf\n",r);
debug("%.8lfms\n",1e3*clock()/CLOCKS_PER_SEC);
return 0;
}
/*
Good luck
-std=c++14 -Wall -O2 -Wextra -Wl,-stack=2147483647
*/