Logu P1966 match queuing, p1966 match queuing
Question Surface
First, study the first question: how to minimize the "distance.
It can be found that the question is to require a suitable pair of two sets of numbers, so that Σ (ai-bi) ^ 2 is the minimum.
The best matching method is to sort the two sets of numbers separately and then pair the two elements with the same position.
Of course, we can find that this conclusion is correct: https://www.luogu.org/wiki/show? Name = % E9 % A2 % 98% E8 % A7 % A3 + P1966
(The following content is for record only)
Meaning: min {Σ (ai-bi) ^ 2 (1 <= I <= n )}
Expand: min {Σ (ai ^ 2 + bi ^ 2-2 * ai * bi )} = min {Sigma ai ^ 2 + Sigma bi ^ 2-sigma 2 * ai * bi}
After careful observation, we can find that the values of Σ ai ^ 2 and Σ bi ^ 2 will not change, so we can only make a fuss about Σ 2 * ai * bi.
To minimize the sum, the Sigma 2 * ai * bi is the largest, and the model of this question is changed to max {Sigma ai * bi }. (2 is a constant, which can be omitted)
After sorting the two arrays respectively, two numbers a and B exist in the first array, and two numbers c and d in the second array.
A <= B c <= d
According to the above speculation, the ac + bd must be the largest. Use the reverse identification method.
If ac + bd is not the largest, there must be a bigger one than it, only ad + bc
If c = d, it is clear that ac + bd = ad + bc will not be larger.
If c <d, then
Ac + bd <ad + bc
Ac-ad <bc-bd
A * (c-d) <B * (c-d) // c-d <0
A> B, conflicts with a <= B
The next question is how to get the minimum distance.
First, read the a1 and B arrays. Put a1 into a struct array a. The struct has members a, B, num. a indicates the value of the corresponding position in the a1 array, num indicates the initial position, and B is empty.
In this case, x1 is the B array at the start.
Then, sort a by the keyword "a" of the struct, and sort B (all from small to large ). Then, assign the elements in B to the members of a in the order of this time (I would like to see it ). In this way, we can obtain the best matching method (after the numbers of the two groups are sorted separately, the two elements with the same position are paired ).
Then, sort a by the struct member num as the keyword. In this case, x2 is obtained, which is a new array consisting of struct member B in.
Then, the problem is converted to converting x1 to x2 with the minimum number of steps when only two adjacent numbers can be exchanged.
The method here is to change each number in x1 to its last position in x2. The problem is to change the new x1 to the minimum number of steps from small to large.
The answer to this question is actually the number of reverse pairs of the new x1. Because: each exchange of two adjacent numbers does not change the relative positions of the other numbers and the two numbers, so it only causes the reverse order to add 1 to the number, minus 1 or not. Then, we can try to make every exchange happen to exchange two numbers in the reverse order (obviously we can do this ). Here is an explanation: http://blog.csdn.net/sunmenggmail/article/details/8151793
1 #include<cstdio> 2 #include<algorithm> 3 #include<map> 4 #define md 99999997 5 using namespace std; 6 typedef long long LL; 7 struct X 8 { 9 LL a,b,num;10 friend bool operator<(const X& a,const X& b)11 {12 return a.a<b.a;13 }14 }a[100100];15 map<LL,LL> ma;16 LL now,n;17 LL x1[100100],ans,t1[100100];18 bool cmp(const X& a,const X& b)19 {20 return a.num<b.num;21 }22 void sort2(LL l,LL r)23 {24 if(l==r) return;25 LL m=(l+r)>>1,i,j,k;26 sort2(l,m);27 sort2(m+1,r);28 for(i=k=l,j=m+1;i<=m&&j<=r;)29 {30 if(x1[i]>x1[j])31 {32 ans=(ans+m+1-i+md)%md;33 t1[k++]=x1[j++];34 }35 else36 t1[k++]=x1[i++];37 }38 for(;i<=m;)39 t1[k++]=x1[i++];40 for(;j<=r;)41 t1[k++]=x1[j++];42 for(i=l;i<=r;i++)43 x1[i]=t1[i];44 }45 int main()46 {47 LL i;48 //freopen("testdata.in","r",stdin);49 scanf("%lld",&n);50 for(i=1;i<=n;i++)51 scanf("%lld",&a[i].a);52 for(i=1;i<=n;i++)53 {54 scanf("%lld",&a[i].b);55 x1[i]=t1[i]=a[i].b;56 a[i].num=i;57 }58 sort(a+1,a+n+1);59 sort(t1+1,t1+n+1);60 for(i=1;i<=n;i++)61 a[i].b=t1[i];62 sort(a+1,a+n+1,cmp);63 for(i=1;i<=n;i++)64 ma[a[i].b]=++now;65 for(i=1;i<=n;i++)66 x1[i]=ma[x1[i]];67 sort2(1,n);68 printf("%lld",ans);69 return 0;70 }
Error code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define md 99999997 5 using namespace std; 6 typedef long long LL; 7 struct X 8 { 9 LL a,b;10 friend bool operator<(const X& a,const X& b)11 {12 return a.a<b.a;13 }14 }a[100100];15 LL a1[100100],t1[100100];16 LL n,ans;17 void sort2(LL l,LL r)18 {19 if(l==r) return;20 LL m=(l+r)>>1,i,j,k;21 sort2(l,m);22 sort2(m+1,r);23 for(i=k=l,j=m+1;i<=m&&j<=r;)24 {25 if(a1[i]>a1[j])26 {27 ans=(ans+m+1-i+md)%md;28 t1[k++]=a1[j++];29 }30 else31 t1[k++]=a1[i++];32 }33 for(;i<=m;)34 t1[k++]=a1[i++];35 for(;j<=r;)36 t1[k++]=a1[j++];37 for(i=l;i<=r;i++)38 a1[i]=t1[i];39 }40 int main()41 {42 LL i;43 //freopen("testdata.in","r",stdin);44 scanf("%lld",&n);45 for(i=1;i<=n;i++)46 scanf("%lld",&a[i].a);47 for(i=1;i<=n;i++)48 scanf("%lld",&a[i].b);49 sort(a+1,a+n+1);50 for(i=1;i<=n;i++)51 a1[i]=a[i].b;52 sort2(1,n);53 printf("%lld\n",ans);54 return 0;55 }
Or na1ve.