題意:給出A、B、C,按照給出的公式推出每一個點,添加每一個點時,求出相應的最短距離,所有最短距離加和
因爲是隨機點,不可能有邊界數據,所以可以爆搞
每次找(0,R-1)區間的最近點對(R爲上一個最近點對裏面編號最大的),然後加上R到N裏面所有的距離(相乘即可)
這題搞出來的。。。應該不是什麼正規解法。。。跑了19015ms。。。還是太水了
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 500050;
typedef struct Point
{
int Id;
int No;
LL x,y;
Point(LL _x=0,LL _y=0,int _Id=0):x(_x),y(_y),Id(_Id){}
bool operator < (const Point &a) const{
return x<a.x || (x==a.x && y<a.y);
}
}Point;
typedef struct Pair
{
LL dis;
int na;
int nb;
bool operator < (const Pair &a) const{
return dis<a.dis ;
}
} Pair;
int n;
Point P[maxn];
Point p[maxn],py[maxn];
int cmpy(Point a, Point b)
{
return a.y < b.y;
}
Pair dis(Point a, Point b)
{
Pair p;
p.dis=(a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
p.na=a.No;
p.nb=b.No;
return p;
}
Pair closest( int l, int r )
{
if( l+1 == r )
return dis( p[l], p[r]) ;
if( l+2 == r )
return min( dis(p[l],p[l+1]), min( dis(p[l+1],p[r]), dis(p[l],p[r]) ) ) ;
int mid = (l+r)/2 ;
Pair pr = min( closest(l,mid), closest(mid+1,r) ) ;
int i, j, cnt=0 ;
for( i=l; i<=r; i++ ){
if( p[i].x >= p[mid].x-pr.dis && p[i].x <= p[mid].x+pr.dis ){
py[cnt++] = p[i] ;
}
}
sort( py, py+cnt, cmpy ) ;
for( i=0; i<cnt; i++ ){
for( j=i+1; j<cnt && (py[j].y-py[i].y)*(py[j].y-py[i].y)<pr.dis; j++ ){
// py數組中的點是按照y座標升序的
pr = min( pr, dis(py[i],py[j]) ) ;
}
}
return pr ;
}
int main()
{
int T,n;
LL ax,ay,bx,by,cx,cy;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&ax,&bx,&cx,&ay,&by,&cy);
P[0]=Point(0,0,0);
for(int i=1;i<=n;i++)
{
LL x = (P[i-1].x*ax + bx)%cx;
LL y = (P[i-1].y*ay + by)%cy;
P[i] = Point(x,y,i);
}
int end=n;
LL ans=0;
while(end>1)
{
for(int i = 0;i < end;i++)
p[i] = P[i+1];
sort(p, p+end);
for(int i = 0;i < end;i++)
p[i].No = i;
Pair pr = closest(0,end-1);
int Max = max(p[pr.na].Id,p[pr.nb].Id);
ans += (end-Max+1)*dis(p[pr.na],p[pr.nb]).dis;
end = Max-1;
}
printf("%I64d\n",ans);
}
return 0;
}