+ Seeking to reverse thinking matches queuing (Los Valley P1966)

Match queue

Title Description

Han Han matches have two boxes, each box containing n a match, each match has a high degree. The pack now matches each in a row, the same column matches different heights, the distance defined between two matches as: Σ (ai-bi) ^ 2

Where ai represents the height of the first matches in the i-th row matches, bi represents the height of the second column of the i-th match matches.

Column matches the position of each adjacent two of the matches can be exchanged by exchanging you that the minimum distance between the two matches. Will get this minimum distance, the exchange requires a minimum number of times? If this number is too big, the minimum switching frequency and outputs the result to the modulo 10 ^ 8-3.

Input Format

Total three rows, the first row contains an integer n, denotes the number of matches per box.

The second row there are n integers, each between two integers separated by a space, the first column height matches.

The third row there are n integers, each between two integers separated by a space, the second column height matches.

Output Format

An integer representing the minimum switching frequency and the results of the modulo 10 ^ 8-3.


To push the first equation [Sigma (AI-BI) ^ 2 = [Sigma (BI ^ AI ^ 2 + 2-2 AI BI) can be found ai ^ 2 + bi ^ 2 sum is constant, just find the maximum ai * bi value;

Can be found, when ai and bi are arranged in ascending order, ai * bi is the largest;

So after both ai and bi can be discretized to ai ascending sequence as the template, the arrangement becomes bi ai of the order;

It is conceivable that this is a request to reverse;

Many solution method, I use the weights tree line;

Code:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100010;
const int M=2000100;
const LL mod=1e8-3;
int n,a[N],a1[N],b[N],b1[N],sum,pos[N];
LL ans;
struct Node{
	int l,r,w;
}tr[N*4];
void build(int l,int r,int k){
	tr[k].l=l,tr[k].r=r;
	if(l==r){
		tr[k].w=0;
		return;
	}
	int d=(l+r)>>1;
	build(l,d,ls);
	build(d+1,r,rs);
	tr[k].w=tr[ls].w+tr[rs].w;
}
void add(int p,int k){
	if(tr[k].l==tr[k].r){
		tr[k].w++;
		return;
	}
	int d=(tr[k].l+tr[k].r)>>1;
	if(p<=d) add(p,ls);
	else add(p,rs);
	tr[k].w=tr[ls].w+tr[rs].w;
}
void query(int ll,int rr,int k){
	if(tr[k].l>=ll&&tr[k].r<=rr){
		sum+=tr[k].w;
		return;
	}
	int d=(tr[k].l+tr[k].r)>>1;
	if(ll<=d) query(ll,rr,ls);
	if(rr>d) query(ll,rr,rs);
}
int main(){	
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]),a1[i]=a[i];
	for(int i=1;i<=n;i++) scanf("%d",&b[i]),b1[i]=b[i];
	sort(a1+1,a1+1+n),sort(b1+1,b1+1+n);
	for(int i=1;i<=n;i++){
		a[i]=lower_bound(a1+1,a1+n+1,a[i])-a1;
		b[i]=lower_bound(b1+1,b1+n+1,b[i])-b1;
	}
	for(int i=1;i<=n;i++) pos[a[i]]=i;
	build(1,n,1);
	for(int i=1;i<=n;i++){
		sum=0;
		query(pos[b[i]]+1,n,1);
		(ans+=sum)%=mod;
		add(pos[b[i]],1);
	}
	cout<<ans<<endl;
	return 0;
}

Published 264 original articles · won praise 46 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_44291254/article/details/105206747