是这样的

是这样的,我的 \(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
*/
posted @ 2024-08-10 15:52  BYR_KKK  阅读(26)  评论(0编辑  收藏  举报