HDU4631(标程代码)

 1 /*将x从小到大排序,每次插入一个点,直接找比这个点的x大的第一个,然后从这个开始向两边找
 2 ,找点的下标用多重容器实现*/
 3 #include<stdio.h>
 4 #include<string.h>
 5 #include<algorithm>
 6 #include<set>
 7 #include<algorithm>
 8 #include<iostream>
 9 using namespace std;
10 struct point
11 {
12     __int64 x,y;
13     bool operator<(const point &a) const
14     {
15         return x<a.x;
16     }
17 };
18 void cacl(__int64 n,__int64 x[])
19 {
20     __int64 a,b,c;
21     scanf("%I64d%I64d%I64d",&a,&b,&c);
22     int i;
23     x[0]=0;
24     for(i=1;i<=n;i++)
25      x[i]=(x[i-1]*a+b)%c;
26 }
27 __int64 min(__int64 a,__int64 b)
28 {
29     if(a<b) return a;
30     return b;
31 }
32 __int64 x[500005],y[500005],n;
33 void find()
34 {
35    __int64 i,j;
36    __int64 ans,sum;
37    __int64 m1,m2;
38    scanf("%I64d",&n);
39     cacl(n,x);
40     cacl(n,y);
41       //for(i=1;i<=n;i++)
42     //    printf("%I64d %I64d
",x[i],y[i]);
43    ans=(__int64)1<<60;
44    sum=0;
45    multiset<point> M;
46    for(i=1;i<=n;i++)
47    {
48         point p;
49        p.x=x[i]; p.y=y[i];
50 
51        if(i>1)//从第二个点开始
52        {
53          multiset<point>::iterator it=M.lower_bound(p),e;
54          for(e=it;e!=M.end();e++)
55          {
56            m1=e->x-p.x;////差值
57            if(m1*m1>=ans) break;
58            m2=e->y-p.y;
59            ans=min(ans,m1*m1+m2*m2);
60          }
61          for(e=it;e!=M.begin();)
62          {
63              e--;//防止重复,上面已经找过it了
64            m1=e->x-p.x;
65            if(m1*m1>=ans) break;
66            m2=e->y-p.y;
67            ans=ans=min(ans,m1*m1+m2*m2);
68          }
69          sum=sum+ans;
70        }
71       M.insert(p);
72    }
73    printf("%I64d
",sum);
74 }
75 int main()
76 {
77     int t;
78     scanf("%d",&t);
79     while(t--)
80     {
81         find();
82     }
83     return 0;
84 }
原文地址:https://www.cnblogs.com/okboy/p/3228089.html