hdu 4361 2013多校联合训练第3场最后一题

来源:互联网 发布:销售数据统计表 编辑:程序博客网 时间:2024/05/24 05:58

题目有n个点  初始时先加入一个点到集合中,然后依次加入点,直到集合中的点的个数为n为止,每加一个点,算一次集合内所有点之间的最短距离,输出这个距离;为了避免输出过多,把每次要输出的结果相加后,每组只输出一个值;

细节见代码注释

#include<cstdio>#include<algorithm>#include<set>#define INF 1e18using namespace std;long long n,Ax,Ay,Az,Bx,By,Bz;struct point{long long x,y;bool operator <(const point& b)const//递增排序{if(x==b.x) return y<b.y;//二级排序return x<b.x;}};typedef set<point>::iterator SetIt;inline point &xy(point &x)//迭代计算,出下一个点{x.x=(x.x*Ax+Ay)%Az;x.y=(x.y*Bx+By)%Bz;return x;}void deal(){set<point> se;long long ans=0,milen=INF,temp,i;point now;now.x=now.y=0;se.insert(xy(now));//插入第一个点for(i=2;i<=n;i++){SetIt it=se.lower_bound(xy(now));//二分查找,查找当前的点需要进位子SetIt it1=it,it2=it;while(it1!=se.begin())//向左扩张{--it1;temp=(it1->x-now.x)*(it1->x-now.x);if(temp>=milen) break;temp+=(it1->y-now.y)*(it1->y-now.y);milen=min(milen,temp);}while(it2!=se.end())//向右扩张{temp=(it2->x-now.x)*(it2->x-now.x);if(temp>=milen) break;temp+=(it2->y-now.y)*(it2->y-now.y);milen=min(milen,temp);++it2;}se.insert(now);// 插入ans+=milen;}printf("%I64d\n",ans);}int main(){freopen("in.txt","r",stdin);int T;scanf("%d",&T);while(T--){scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&n,&Ax,&Ay,&Az,&Bx,&By,&Bz);deal();}return 0;}


原创粉丝点击