本地 AC,为何 TLE
  • 板块学术版
  • 楼主Vct14
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/12/28 14:48
  • 上次更新2024/12/28 18:03:30
查看原帖
本地 AC,为何 TLE
677609
Vct14楼主2024/12/28 14:48

上文。这次我都改成 void 了()

本地很快可以跑出结果,但是交到 OJ 里跑 55 秒都跑不出来。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<fstream>
#include<sstream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<cassert>
#include<complex>
using namespace std;

#include<cmath>

#define LL long long

const double pi = acos(-1);
const double hpi = pi * 0.5;

struct MyVec
{
	int x,y;
	double rot;
	
	inline MyVec&operator =(const MyVec&a)
	{
		x=a.x;y=a.y;rot=a.rot;
	}
	
	inline int norm()
	{
		if(!x && !y) {rot=0; return 0;}
		int t = __gcd(abs(x),abs(y));
		x/=t;y/=t;
		rot = atan2(y,x);
		return 0;
	}
	
	inline MyVec(int _x=0,int _y=0):x(_x),y(_y)
	{
		norm();
	}
	inline void rotate()
	{
		swap(x,y); x=-x;
		rot+=hpi;
	}
	inline void inverse()
	{
		x=-x;y=-y;
		rot+=pi;
	}
};

inline MyVec operator + (MyVec a, MyVec b)
{
	return MyVec(a.x + b.x, a.y + b.y);
}

inline MyVec operator - (MyVec a, MyVec b)
{
	return MyVec(a.x - b.x, a.y - b.y);
}

bool operator < (const MyVec&a, const MyVec&b)
{
	return a.x != b.x ? a.x < b.x : a.y < b.y;
}

inline LL dot(LL a, LL b, LL c, LL d){return a * c + b * d;}
inline LL cross(LL a, LL b, LL c, LL d){return a * d - b * c;}

inline bool cmp(const MyVec&a, const MyVec&b) // a < b
{
	if(fabs(a.rot - b.rot) > hpi) return a.rot < b.rot;
	return cross(a.x,a.y,b.x,b.y)>0;
}

struct Event
{
	MyVec v;
	int x,y;
	inline void set(int _x, int _y, MyVec _v)
	{
		v = _v;
		x = _x;
		y = _y;
	}
}dat;

inline bool operator < (const Event&a,const Event&b)
{
	return cmp(b.v,a.v);// a.v > b.v
}

const int MaxN = 3000 + 10;

int X[MaxN],Y[MaxN];
int N;
LL best[MaxN];
LL SX[MaxN],SY[MaxN];
int pos[MaxN],A[MaxN];

MyVec cur,V[MaxN],dest;

inline bool always(int a, int b){return X[a]==X[b]&&Y[a]==Y[b];}

bool cmpProj(int a, int b)// Proj(a) > Proj(b)
{
	if(always(a,b)) return a < b;
	LL la = dot(X[a],Y[a],cur.x,cur.y);
	LL lb = dot(X[b],Y[b],cur.x,cur.y);
	if(la != lb) return la > lb;
	// Calc_Next will never enter this part
	MyVec tmp;
	tmp=cur; tmp.rotate();
	// Pay Attention Here
	// Consider the case swap of a, b occur on time cur
	return dot(X[a],Y[a],tmp.x,tmp.y)
			<dot(X[b],Y[b],tmp.x,tmp.y);
}

MyVec Calc_Next(int x, int y)
{
	MyVec nxt(X[x]-X[y],Y[x]-Y[y]),tmp;
	nxt.rotate();
	nxt.rot -= 4 * pi;
	while(cmp(nxt,cur)) nxt.inverse();
	tmp = cur;
	while(true)
	{
		cur = nxt; cur.rotate();
		if(cmpProj(y,x))
		{
			cur = tmp;
			return nxt;
		}
		nxt.inverse();
	}
}

inline void check(int a, LL x, LL y)
{
	best[a]=max(best[a],x*x+y*y);
}

int main()
{
//	freopen("airship.in","r",stdin);
//	freopen("airship.out","w",stdout);
	
	scanf("%d", &N);
	
	//cerr<<N<<endl;
	LL tt=0,xx,yy;
	
	scanf("%lld %lld",&xx,&yy);
	//cin>>xx>>yy;
	//cerr << xx<<" "<<yy<<endl;
	
	for(int i=1;i<=N;++i)
	{
		scanf("%d %d",X+i,Y+i);
		V[i]=MyVec(X[i],Y[i]);
		A[i]=i;
		
	//	cerr << X[i]<<" "<<Y[i]<<endl;
		tt+=max(0ll,xx*X[i]+yy*Y[i]);
		
	//	cerr << xx*X[i]+yy*Y[i]<<endl;
		
	}
	printf("%lld\n",tt);
	
	cur = V[1]; dest = cur;
	dest.inverse();
	dest.inverse();
	dest.rotate();
	
	sort(A+1,A+1+N,cmpProj);
	
	SX[0]=SY[0]=0;
	for(int i=1;i<=N;++i) {
		pos[A[i]] = i;
		check(i, SX[i]=SX[i-1]+X[A[i]],SY[i]=SY[i-1]+Y[A[i]]);
	}
	
	priority_queue<Event> Q;
	for(int i=1;i<N;++i)
		if(!always(A[i],A[i+1]))
		{
			dat.set(A[i],A[i+1],Calc_Next(A[i],A[i+1]));
			Q.push(dat);
		}
	
	while(!Q.empty())
	{
		Event t = Q.top(); Q.pop();
		MyVec v;
		v = t.v;
		
		if(cmp(dest, v)) break;
		
		int x = t.x, y = t.y;
		if(pos[x] + 1 != pos[y]) continue;
		int a = pos[x], b = pos[y];
		
		cur = v;
		
		// Swap(a, b)
		swap(A[pos[x]], A[pos[y]]);
		swap(pos[x], pos[y]);
		
		check(a,SX[a]=SX[a-1]+X[y],SY[a]=SY[a-1]+Y[y]);
		
		if(a > 1 && !always(A[a-1],A[a]))
		{
			dat.set(A[a-1],A[a],Calc_Next(A[a-1],A[a]));
			Q.push(dat);
		}
		if(!always(A[a], A[a+1]))
		{
			dat.set(A[a],A[a+1],Calc_Next(A[a],A[a+1]));
			Q.push(dat);
		}
		if(a < N-1 && !always(A[a+1], A[a+2]))
		{
			dat.set(A[a+1],A[a+2],Calc_Next(A[a+1],A[a+2]));
			Q.push(dat);
		}
	}
	
	printf("%lld\n", *max_element(best+1,best+1+N));
	for(int i=1;i<=N;++i)
	{
		if(i>1)printf(" ");
		printf("%lld",best[i]);
	}
	puts("");
}
2024/12/28 14:48
加载中...