Description

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

Input

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

Output

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

Sample Input

【样例输入】
3
130 150 140
2
2 3
1 3

Sample Output

1
0
3
【样例说明】
未进行任何操作时,(2,3)满足条件;
操作1结束后,序列为130 140 150,不存在满足ihj的(i,j)对;
操作2结束后,序列为150 140 130,(1,2),(1,3),(2,3)共3对满足条件的(i,j)

Solution

首先上来先离散化一下。
可以发现,交换两个位置对答案的影响只和两个位置中间的数的大小有关
所以可以分块加树状数组,两端零碎的暴力统计,中间成块的每一块开一个树状数组,就可以统计比两端大/小的数的个数了。

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N (20000+100)
using namespace std; int n,m,unit,num,bnum,ans,l,r;
int a[N],b[N],L[N],R[N],ID[N]; struct Node
{
int c[N];
int lowbit(int x){return x&-x;}
void Update(int x,int v){for (;x<=n;c[x]+=v,x+=lowbit(x));}
int Query(int x){int s=; for (;x;s+=c[x],x-=lowbit(x));return s;}
}T[]; void Init()
{
for (int i=; i<=n; ++i) b[i]=a[i];
sort(b+,b+n+);
bnum=unique(b+,b+n+)-b-;
for (int i=; i<=n; ++i)
a[i]=lower_bound(b+,b+bnum+,a[i])-b;
} void Build()
{
unit=sqrt(n);
num=n/unit+(n%unit!=);
for (int i=; i<=num; ++i)
L[i]=(i-)*unit+,R[i]=i*unit;
R[num]=n;
for (int i=; i<=num; ++i)
for (int j=L[i]; j<=R[i]; ++j)
ID[j]=i,T[i].Update(a[j],);
} void check(int x,int l,int r)
{
if (a[x]>a[l]) ans--;
if (a[x]<a[l]) ans++;
if (a[x]<a[r]) ans--;
if (a[x]>a[r]) ans++;
} void Solve(int l,int r)
{
if (a[l]>a[r]) ans++;
if (a[l]<a[r]) ans--;
T[ID[l]].Update(a[l],); T[ID[l]].Update(a[r],-);
T[ID[r]].Update(a[r],); T[ID[r]].Update(a[l],-);
if (ID[l]==ID[r])
{
for (int i=l+; i<=r-; ++i)
check(i,l,r);
printf("%d\n",ans); return;
}
for (int i=l+; i<=R[ID[l]]; ++i) check(i,l,r);
for (int i=L[ID[r]]; i<=r-; ++i) check(i,l,r);
for (int i=ID[l]+; i<=ID[r]-; ++i)
{
int l1=T[i].Query(a[l]-);
int l2=T[i].Query(n)-T[i].Query(a[l]);
int r1=T[i].Query(a[r]-);
int r2=T[i].Query(n)-T[i].Query(a[r]);
ans+=l1-l2+r2-r1;
}
printf("%d\n",ans);
} int main()
{
scanf("%d",&n);
for (int i=; i<=n; ++i)
scanf("%d",&a[i]);
Init(); Build();
for (int i=; i<=n; ++i)
{
ans+=T[].Query(n)-T[].Query(a[i]);
T[].Update(a[i],);
}
printf("%d\n",ans);
scanf("%d",&m);
for (int i=; i<=m; ++i)
{
scanf("%d%d",&l,&r); if (l>r) swap(l,r);
swap(a[l],a[r]); Solve(l,r);
}
}

BZOJ2141:排队(分块,树状数组)的更多相关文章

  1. 【bzoj2141】排队 分块+树状数组

    题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别, ...

  2. BZOJ_2141_排队_树状数组+分块

    BZOJ2141_排队_树状数组+分块 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了 ...

  3. 【BZOJ 3295】动态逆序对 - 分块+树状数组

    题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...

  4. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  5. 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu

    https://www.codechef.com/problems/FNCS [题意] [思路] 把n个函数分成√n块,预处理出每块中各个点(n个)被块中函数(√n个)覆盖的次数 查询时求前缀和,对于 ...

  6. bzoj2141: 排队(分块+树状数组)

    块套树为什么会这么快.. 先跑出原序列逆序对. 显然交换两个位置$l,r$,对$[1,l),(r,n]$里的数没有影响,所以只需要考虑$[l,r]$内的数. 设$(l,r)$内的数$a_i$,则按以下 ...

  7. BZOJ 2141 排队(分块+树状数组)

    题意 第一行为一个正整数n,表示小朋友的数量:第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高:第三行为一个正整数m,表示交换操作的次数:以下m行每行包含两个正整数 ...

  8. Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对

    3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2886  Solved: 924[Submit][Stat ...

  9. 【XSY2111】Chef and Churus 分块 树状数组

    题目描述 有一个长度为\(n\)的数组\(A\)和\(n\)个区间\([l_i,r_i]\),有\(q\)次操作: \(1~x~y\):把\(a_x\)改成\(y\) \(2~x~y\):求第\(l\ ...

随机推荐

  1. Codeforces 949E Binary Cards

    Description 给出一个长度为 \(n\) 的数组,求使得用最少数量的 \(2^k\) 或 \(-2^k\) 的数,使得数组中的每一个元素都可以被你选出的 \(2\) 的次幂表示 题面 Sol ...

  2. js实现页面跳转的八种方式

    整理一下JavaScript八种跳转方式,欢迎评论补充! 第一种方法: <script> window.location.replace('http://www.cnblogs.com/c ...

  3. VMware下安装Linux(Centos)步骤

    VMware下安装Linux(Centos)步骤 准备步骤:(安装软件教程采用 VMware 9 .Centos6.5 为例) 启动VMware的画面 点击File--->New Virtua ...

  4. Spring学习笔记:Spring动态组装打印机

    一.如何开发一个打印机 1.可灵活配置使用彩色魔盒或灰色魔盒 2.可灵活配置打印页面的大小 二.打印机功能的实现依赖于魔盒和纸张 三.步骤: 1.定义墨盒和纸张的接口标准 package cn.pri ...

  5. PHP 八种基本的数据类型

    四种标量类型: boolean (布尔型) integer (整型) float (浮点型, 也称作 double) string (字符串) 两种复合类型: array (数组) object (对 ...

  6. Python OOP面向对象

    一.什么是面向对象的程序设计 1.面向过程 程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式. 优点是 ...

  7. 用css3+js写了一个钟表

    有一天看到css3旋转这个属性,突发奇想的写了一个钟表(没做浏览器兼容),来一起看看是怎么写的吧! 先给个成品图,最终结果是个样子的(动态的). 首先,思考了一下页面的布局,大致需要4层div,最底层 ...

  8. js中的this--执行上下文

    条件:函数调用的时候  才有执行上下文 this 不同情况的调用,this也不同 1)当函数直接打点调用,此时的this 是window 2)事件触发函数,此时的this是触发这个事件的对象 3)当对 ...

  9. 解决Non-resolvable parent POM: Could not find artifact 出现的问题

    在编译spring boot 多模块项目的时候,往往出现 Non-resolvable parent POM: Could not find artifact 后面跟一串其它信息,网上大部分解决方案是 ...

  10. opencv 从摄像头中读取视频并保存(c++版)

    原文:http://blog.csdn.net/zhongshijunacm/article/details/68947890 OpenCV中的视频操作函数如下表所列: VideoCapture Vi ...