列表

详情


NC211255. 排队

描述

排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。

输入描述

第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。

输出描述

输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。

示例1

输入:

3
130 150 140
2
2 3
1 3

输出:

1
0
3

说明:

未进行任何操作时,(2,3)满足条件;
操作1结束后,序列为130 140 150,不存在满足i<j且hi>hj的(i,j)对;
操作2结束后,序列为150 140 130,(1,2),(1,3),(2,3)共3对满足条件的(i,j)。
「数据规模和约定」
对于100%的数据,1≤m≤2*103,1≤n≤2*104,1≤hi≤109,ai≠bi,1≤ai,bi≤n。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 87ms, 内存消耗: 22652K, 提交时间: 2021-10-26 13:09:54

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

int a[20010],lsh[20010];
int t,n;
ll tree[200][20010];

inline int lowbit(int x){
	return x&(-x);
}

void add(int x,int y,int k){
	for(int i=y;i<=n;i+=lowbit(i)) tree[x][i]+=k;
}

ll find(int x,int y){
	ll ans=0;
	for(int i=y;i>0;i-=lowbit(i)) ans+=tree[x][i];
	return ans;
}

int main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int m;
	cin>>n;
	t=sqrt(n);
	for(int i=1;i<=n;i++){
		cin>>a[i]; lsh[i]=a[i];
	}
	sort(lsh+1,lsh+n+1);
	int cnt=unique(lsh+1,lsh+n+1)-lsh-1;
	for(int i=1;i<=n;i++) a[i]=cnt-(lower_bound(lsh+1,lsh+cnt+1,a[i])-lsh)+1;
	
	ll ans=0;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=i/t;j++) ans+=find(j,a[i]-1);
		add(i/t,a[i],1);
	}
	cout<<ans<<"\n";
	cin>>m;
	int x,y;
	while(m--){
		cin>>x>>y;
		if(x>y) swap(x,y);
		//cout<<x/t<<" "<<y/t<<"\n";
		if(x/t==y/t){
			for(int i=x+1;i<y;i++){
				if(a[i]>a[x]) ans--;
				if(a[i]<a[x]) ans++;
				if(a[i]>a[y]) ans++;
				if(a[i]<a[y]) ans--;
			}
		}
		else{
			//cout<<ans<<"\n";
			for(int i=x/t+1;i<y/t;i++){
				ans+=find(i,a[x]-1)-(t-find(i,a[x]))-find(i,a[y]-1)+(t-find(i,a[y]));
			}
			//cout<<ans<<'\n';
			for(int i=x+1;i<(x/t+1)*t;i++){
				if(a[i]>a[x]) ans--;
				if(a[i]<a[x]) ans++;
				if(a[i]>a[y]) ans++;
				if(a[i]<a[y]) ans--;
			}
			for(int i=y/t*t;i<y;i++){
				if(a[i]>a[x]) ans--;
				if(a[i]<a[x]) ans++;
				if(a[i]>a[y]) ans++;
				if(a[i]<a[y]) ans--;
		    }
		}
		if(a[x]>a[y]) ans++;
		if(a[x]<a[y]) ans--;
		add(x/t,a[x],-1); add(y/t,a[y],-1);
		swap(a[x],a[y]);
		add(x/t,a[x],1); add(y/t,a[y],1);
		cout<<ans<<'\n';
	}
	return 0;
}

上一题