bzoj 2141 : 排队 分块
2141: 排队
Time Limit: 4 Sec  Memory Limit: 259 MB
Submit: 1169  Solved: 465
[Submit][Status][Discuss]
Description
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足ihj的(i,j)数量。幼儿园阿姨每次会选出两个小朋友,交换他们的位置,请你帮忙计算出每次交换后,序列的杂乱程度。为方便幼儿园阿姨统计,在未进行任何交换操作时,你也应该输出该序列的杂乱程度。
Input
第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi¬,表示交换位置ai与位置bi的小朋友。
Output
输出文件共m行,第i行一个正整数表示交换操作i结束后,序列的杂乱程度。
Sample Input
3
130 150 140
2
2 3
1 3
Sample Output
0
3
#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
const int maxn = 2e4+;
int a[maxn], b[maxn], c[maxn], sum[maxn], l[maxn], r[maxn], belong[maxn];
int block, cnt, n, ans;
int lowbit(int x) {
return x&(-x);
}
void update(int x) {
for(int i = x; i<=n; i+=lowbit(i)) {
sum[i]++;
}
}
int query(int x) {
int ret = ;
for(int i = x; i>; i-=lowbit(i)) {
ret += sum[i];
}
return ret;
}
void rebuild(int x) {
for(int i = l[x]; i<=r[x]; i++)
b[i] = a[i];
sort(b+l[x], b+r[x]+);
}
void pre() {
for(int i = n; i>; i--) {
ans += query(a[i]-);
update(a[i]);
}
for(int i = ; i<=cnt; i++) {
rebuild(i);
}
}
void cmp(int x, int y) {
if(x>y)
ans++;
if(x<y) //不要写else...可能相等
ans--;
}
void solve(int x, int y) {
if(a[x]>a[y])
ans--;
if(a[x]<a[y]) //不要写else!!
ans++;
if(belong[x] == belong[y]) {
for(int i = x+; i<y; i++) {
cmp(a[i], a[x]);
cmp(a[y], a[i]);
}
} else {
for(int i = x+; i<=r[belong[x]]; i++) {
cmp(a[i], a[x]);
cmp(a[y], a[i]);
}
for(int i = l[belong[y]]; i<y; i++) {
cmp(a[i], a[x]);
cmp(a[y], a[i]);
}
for(int i = belong[x]+; i<belong[y]; i++) {
ans -= lower_bound(b+l[i], b+r[i]+, a[x])-b--l[i];
ans += lower_bound(b+l[i], b+r[i]+, a[y])-b--l[i];
ans -= r[i] - (upper_bound(b+l[i], b+r[i]+, a[y])-b-l[i]);
ans += r[i] - (upper_bound(b+l[i], b+r[i]+, a[x])-b-l[i]);
}
}
swap(a[x], a[y]);
rebuild(belong[x]);
rebuild(belong[y]);
}
int main()
{
int m;
cin>>n;
block = sqrt(1.0*n);
if(n%block)
cnt = n/block+;
else
cnt = n/block;
for(int i = ; i<=cnt; i++) {
l[i] = (i-)*block+;
r[i] = i*block;
}
r[cnt] = n;
for(int i = ; i<=n; i++) {
scanf("%d", &a[i]);
c[i-] = a[i];
belong[i] = (i-)/block+;
}
sort(c, c+n);
int tmp = unique(c, c+n)-c;
for(int i = ; i<=n; i++) {
a[i] = b[i] = lower_bound(c, c+tmp, a[i])-c+;
}
pre();
cout<<ans<<endl;
cin>>m;
while(m--) {
int x, y;
scanf("%d%d", &x, &y);
if(x>y)
swap(x, y);
solve(x, y);
printf("%d\n", ans);
}
return ;
}
bzoj 2141 : 排队 分块的更多相关文章
- Bzoj 2141: 排队  分块,逆序对,树状数组
		
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MBSubmit: 1310 Solved: 517[Submit][Status][Discuss] D ...
 - bzoj 2141: 排队
		
2141: 排队 Time Limit: 4 Sec Memory Limit: 259 MB Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我, ...
 - BZOJ 2141 排队(分块+树状数组)
		
题意 第一行为一个正整数n,表示小朋友的数量:第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高:第三行为一个正整数m,表示交换操作的次数:以下m行每行包含两个正整数 ...
 - BZOJ 2141: 排队 [CDQ分治]
		
题意: 交换序列中两个元素,求逆序对 做分块做到这道题...一看不是三维偏序嘛.... 作为不会树套树的蒟蒻就写CDQ分治吧.... 对时间分治...x排序...y树状数组... 交换拆成两个插入两个 ...
 - bzoj 2141 : 排队  (cdq分治+bit)
		
链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2141 思路: 其实就是求动态逆序对...cdq降维,用树状数组前后求两遍逆序对就好了 切水 ...
 - BZOJ 2141  排队(树状数组套treap)
		
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2141 题意:给出一个数列A,每次交换两个数的位置.输出交换后逆序对的个数. 思路:首先, ...
 - BZOJ 2141 排队 (CDQ分治)
		
[BZOJ2141]排队 这道题和动态逆序对比较像(BZOJ-3295 没做过的同学建议先做这题),只是删除操作变成了交换.解法:交换操作可以变成删除加插入操作,那么这题就变成了 (时间,位置,值)的 ...
 - BZOJ 2141 排队(树状数组套主席树)
		
解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...
 - BZOJ - 2141 排队 (动态逆序对,区间线段树套权值线段树)
		
题目链接 交换两个数的位置,只有位于两个数之间的部分会受到影响,因此只需要考虑两个数之间有多少数对a[l]和a[r]产生的贡献发生了变化即可. 感觉像是个带修改的二维偏序问题.(修改点$(x,y)$的 ...
 
随机推荐
- xsqlbuilder使用说明
			
动态构造sql的利器:rapid-xsqlbuider详细说明 特性列表: 动态构造sql条件语句,提供sql拼接与使用占位符两种方式 数据类型的修饰 对SQL注入攻击的防范 问题: 手工构造SQL语 ...
 - 001.web前端-学习了解
			
学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言.下面我们就来了解下这三门技术都是用来实现什么的: 1.html(Hypertext Markup Language)—— ...
 - requirejs + vue 项目搭建
			
以前都是支持 司徒正美 的,毕竟咱们也是跟着 司徒正美 一起走进了前端的世界.所以一般MVVM都是用avalon的,当然也是考虑到项目需要支持IE6,7,8的考虑.当然在用的时候也有一些小坑和bug, ...
 - jquery判断图片是否加载完毕
			
来源: <http://www.2cto.com/kf/201409/331234.html> 利用图片没有加载完成的时候,宽高为0.我们很容易判断图片的一个加载情况.如下: 思路:判断图 ...
 - hdu 5724 Chess  博弈
			
题目链接 一个n行20列的棋盘. 每一行有若干个棋子. 两人轮流操作, 每人每次可以将一个棋子向右移动一个位置, 如果它右边有一个棋子, 就跳过这个棋子, 如果有若干个棋子, 就将这若干个都跳过. 但 ...
 - C++静态库与动态库(简介)
			
C++静态库与动态库 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...
 - SQL Server 恢复过程
			
在恢复过程中.只会分析那些自最后一个检查点之后发生的更改,以确定是否需要重做还是撤销. 在最后一个检查点之前完成的操作都会精确的反应到数据文件中,恢复过程不需要做其它的事. 第一阶段: 分析. 这个阶 ...
 - 与ARM7相比Cortex-M3优势明显
 - CF卡是什么
			
CF卡(Compact Flash)最初是一种用于便携式电子设备的数据存储设备.作为一种存储设备,它革命性的使用了闪存,于1994年首次由SanDisk公司生产并制定了相关规范.当前,它的物理格式已经 ...
 - C语言入门(13)——循环
			
在递归调用中,其实每次递归都是在重复做同样一件事,比如求阶乘就是把n乘到(n-1)!上然后把结果返回.虽说是重复,但每次做都稍微有一点区别(n的值不一样),这种每次都有点区别的重复工作称为迭代. 我们 ...