上文。这次我都改成 void 了()
本地很快可以跑出结果,但是交到 OJ 里跑 5 秒都跑不出来。
#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("");
}