排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。
输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。
#include
#define pb push_back
using namespace std;
const int N = 20010;
int n, m;
int bits[N];
int ma[N];
int cp[N];///每个块排序后储存的数组
int block;
int num;
int bo[N];
int bl[N];
int br[N];
int ans;
int len;
vector id;
int getid(int x)
{
return lower_bound(id.begin(), id.end(), x) - id.begin() + 1;
}
int lowbit(int x)
{
return x & -x;
}
int quary(int x)
{
int ans = 0;
while(x > 0){
ans += bits[x];
x -= lowbit(x);
}
return ans;
}
void update(int x, int v)
{
while(x <= len){
bits[x] += v;
x += lowbit(x);
}
}
void build()
{
block = sqrt(n);
num = n / block;
if(n % block){
num ++;
}
for(int i = 1; i <= n; i ++){
bo[i] = (i - 1) / block + 1;
}
for(int i = 1; i <= num; i ++){
bl[i] = (i - 1) * block + 1;
br[i] = i * block;
}
br[num] = n;
for(int i = 1; i <= num; i ++){
for(int j = bl[i]; j <= br[i]; j ++){
cp[j] = ma[j];
}
sort(cp + bl[i], cp + br[i] + 1);
}
}
void quary_block(int l, int r, int v, int t) ///交换之前就计算,比ma[l]小的ans-- 比 ma[r]小的ans++ 这样就能把两个合并在一起
{
int x = bo[l];
int y = bo[r];
if(x == y){
for(int i = l; i <= r; i ++){
if(ma[i] < v){
ans -= t;
}
else if(ma[i] > v){
ans += t;
}
}
}
else{
for(int i = l; i <= br[x]; i ++){
if(ma[i] < v){
ans -= t;
}
else if(ma[i] > v){
ans += t;
}
}
for(int i = x + 1; i < y; i ++){
ans -= t * (lower_bound(cp + bl[i], cp + br[i] + 1, v) - cp - bl[i]);
ans += t * ((br[i] - bl[i] + 1) - (upper_bound(cp + bl[i], cp + br[i] + 1, v) - cp - bl[i]));
}
for(int i = bl[y]; i <= r; i ++){
if(ma[i] < v){
ans -= t;
}
else if(ma[i] > v){
ans += t;
}
}
}
}
void exchange(int l, int r)
{
if(l > r){
return ;
}
int t;
int opx;
int opy;
int x = bo[l];
int y = bo[r];
if(ma[l] < ma[r]){
ans ++;
}
else if(ma[l] > ma[r]){
ans --;
}
swap(ma[l], ma[r]);
opx = lower_bound(cp + bl[x], cp + br[x] + 1, ma[l]) - cp;
opy = lower_bound(cp + bl[y], cp + br[y] + 1, ma[r]) - cp;
cp[opx] = ma[r];
cp[opy] = ma[l];
t = opx;
while(t - 1 >= bl[x] && cp[t - 1] > cp[t]){
swap(cp[t], cp[t - 1]);
t --;
}
while(t <= br[x] && cp[t + 1] < cp[t]){
swap(cp[t], cp[t + 1]);
t ++;
}
t = opy;
while(t - 1 >= bl[y] && cp[t - 1] > cp[t]){
swap(cp[t], cp[t - 1]);
t --;
}
while(t <= br[y] && cp[t + 1] < cp[t]){
swap(cp[t], cp[t + 1]);
t ++;
}
}
int main(int argc, char const *argv[])
{
while(scanf("%d", &n) == 1){
ans = 0;
memset(bits, 0, sizeof(bits));
for(int i = 1; i <= n; i ++){
scanf("%d", &ma[i]);
id.pb(ma[i]);
}
sort(id.begin(), id.end());
id.erase(unique(id.begin(), id.end()), id.end());
len = id.size();
for(int i = 1; i <= n; i ++){
update(getid(ma[i]), 1);
ans += i - quary(getid(ma[i]));
}
printf("%d\n", ans);
scanf("%d", &m);
for(int i = 0; i < m; i ++){
int l, r;
scanf("%d%d", &l, &r);
if(r < l){
swap(r,l);
}
quary_block(l + 1, r - 1, ma[l], 1);
quary_block(l + 1, r - 1, ma[r], -1);
exchange(l, r);
printf("%d\n", ans);
}
}
return 0;
}