【BZOJ2141】排队 树状数组+分块
【BZOJ2141】排队
Description
排排坐,吃果果,生果甜嗦嗦,大家笑呵呵。你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家乐和和。红星幼儿园的小朋友们排起了长长地队伍,准备吃果果。不过因为小朋友们的身高有所区别,排成的队伍高低错乱,极不美观。设第i个小朋友的身高为hi,我们定义一个序列的杂乱程度为:满足i<j且hi>hj的(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
【样例说明】
未进行任何操作时,(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。
题解:我们先想朴素算法,对于操作(a,b)我们需要求出[a+1,b-1]内比a小、比a大、比b小、比b大的数的个数,这个很容易想到用树状数组,但是树状数组只能离线搞,因此我们想到分块
我们对每个块都开一个树状数组,然后对于操作[i,j]我们先扫一遍中间的大块,用树状数组更新一下答案,然后再暴力枚举两边的小块,时间复杂度O(m*sqrt(n)*log(n))
注意:
1.一开始的初始化逆序对时最好新建一个普通的树状数组来搞,这样应该能大大减小复杂度
2.可能出现两个身高相同的情况,这不应该被算作逆序对处理
3.输入的a可能大于b
4.别忘了特判(a,b)在同一个块里的情况
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int n,nm,m,siz,ans;
int s[150][20010],v[20010],tr[20010];
struct node
{
int num,org;
}p[20010];
bool cmp(node a,node b)
{
return a.num<b.num;
}
int rd()
{
int ret=0; char gc=getchar();
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
void updata(int x,int y,int z)
{
for(int i=y;i<=nm;i+=i&-i) s[x][i]+=z;
}
int query(int x,int y)
{
int i,ret=0;
for(i=y;i;i-=i&-i) ret+=s[x][i];
return ret;
}
int main()
{
n=rd(),siz=int(sqrt(1.0*n));
int i,j,a,b,pre;
for(i=0;i<n;i++) p[i].org=i,p[i].num=rd();
sort(p,p+n,cmp);
for(i=0,pre=-1;i<n;i++)
{
if(p[i].num>pre) pre=p[i].num,nm++;
v[p[i].org]=nm;
}
for(i=n-1;i>=0;i--)
{
updata(i/siz,v[i],1);
for(a=0,j=v[i]-1;j;j-=j&-j) a+=tr[j];
for(ans+=a,j=v[i];j<=nm;j+=j&-j) tr[j]++;
}
printf("%d\n",ans);
m=rd();
for(i=1;i<=m;i++)
{
a=rd()-1,b=rd()-1;
if(a>b) swap(a,b);
if(a/siz==b/siz)
{
for(j=a+1;j<b;j++) ans+=(v[a]<v[j])+(v[j]<v[b])-(v[a]>v[j])-(v[j]>v[b]);
ans+=(v[a]<v[b])-(v[a]>v[b]);
swap(v[a],v[b]);
printf("%d\n",ans);
continue;
}
for(j=a/siz+1;j<b/siz;j++) ans+=-query(j,v[a]-1)-query(j,v[a])+query(j,v[b]-1)+query(j,v[b]);
for(j=a+1;j<(a/siz+1)*siz;j++) ans+=(v[a]<v[j])+(v[j]<v[b])-(v[a]>v[j])-(v[j]>v[b]);
for(j=b/siz*siz;j<b;j++) ans+=(v[a]<v[j])+(v[j]<v[b])-(v[a]>v[j])-(v[j]>v[b]);
ans+=(v[a]<v[b])-(v[a]>v[b]);
updata(a/siz,v[a],-1),updata(b/siz,v[b],-1);
swap(v[a],v[b]);
updata(a/siz,v[a],1),updata(b/siz,v[b],1);
printf("%d\n",ans);
}
return 0;
}
【BZOJ2141】排队 树状数组+分块的更多相关文章
- BZOJ2141 排队 树状数组 分块
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2141.html 题目传送门 - BZOJ2141 题意 给定一个序列 $a$ ,先输出原先的逆序对数. ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- BZOJ_2141_排队_树状数组+分块
BZOJ2141_排队_树状数组+分块 Description 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了 ...
- 【bzoj4889】[Tjoi2017]不勤劳的图书管理员 树状数组+分块+二分
题目描述(转自洛谷) 加里敦大学有个帝国图书馆,小豆是图书馆阅览室的一个书籍管理员.他的任务是把书排成有序的,所以无序的书让他产生厌烦,两本乱序的书会让小豆产生这两本书页数的和的厌烦度.现在有n本被打 ...
- bzoj 4765 普通计算姬(树状数组 + 分块)
http://www.lydsy.com/JudgeOnline/problem.php?id=4765 很nice的一道题啊(可能是因为卡了n久终于做出来了 题意就是给你一棵带点权的有根树,sum( ...
- COGS.1822.[AHOI2013]作业(莫队 树状数组/分块)
题目链接: COGS.BZOJ3236 Upd: 树状数组实现的是单点加 区间求和,采用值域分块可以\(O(1)\)修改\(O(sqrt(n))\)查询.同BZOJ3809. 莫队为\(O(n^{1. ...
- ACM-ICPC 2018 沈阳赛区网络预赛 J. Ka Chang(树状数组+分块)
Given a rooted tree ( the root is node 1 ) of N nodes. Initially, each node has zero point. Then, yo ...
- Codeforces Round #404 (Div. 2) A,B,C,D,E 暴力,暴力,二分,范德蒙恒等式,树状数组+分块
题目链接:http://codeforces.com/contest/785 A. Anton and Polyhedrons time limit per test 2 seconds memory ...
- gym 100589A queries on the Tree 树状数组 + 分块
题目传送门 题目大意: 给定一颗根节点为1的树,有两种操作,第一种操作是将与根节点距离为L的节点权值全部加上val,第二个操作是查询以x为根节点的子树的权重. 思路: 思考后发现,以dfs序建立树状数 ...
随机推荐
- java-el+jstl+jsbc综合示例
项目结构: 项目展示: 数据库: /* SQLyog Ultimate v12.09 (64 bit) MySQL - 5.5.53 : Database - product ************ ...
- JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比
1.什么是JVM? JVM本质上就是一个软件,是计算机硬件的一层软件抽象,在这之上才能够运行Java程序,JAVA在编译后会生成类似于汇编语言的JVM字节码,与C语言编译后产生的汇编语言不同的是, ...
- Deep Learning 经典网路回顾#之LeNet、AlexNet、GoogLeNet、VGG、ResNet
#Deep Learning回顾#之LeNet.AlexNet.GoogLeNet.VGG.ResNet 深入浅出——网络模型中Inception的作用与结构全解析 图像识别中的深度残差学习(Deep ...
- 【转】Microsoft .Net Remoting之Remoting事件处理全接触
Remoting事件处理全接触 前言:在Remoting中处理事件其实并不复杂,但其中有些技巧需要你去挖掘出来.正是这些技巧,仿佛森严的壁垒,让许多人望而生畏,或者是不知所谓,最后放弃了事件在Remo ...
- Spring 4 官方文档学习(十)数据访问之JDBC
说明:未修订版,阅读起来极度困难 1.Spring框架JDBC的介绍 Spring JDBC - who does what? 动作 Spring 你 定义连接参数 是 打开连接 是 指定SQ ...
- C++ 数据抽象
C++ 数据抽象数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节. 数据抽象是一种依赖于接口和实现分离的编程(设计)技术. 让我们举一个现实生活中的真实例子, ...
- yasm开源汇编器分析
https://www.google.com.hk/search?q=yasm&oq=yasm&aqs=chrome..69i57&sourceid=chrome&es ...
- mysql 从sql存储文件恢复数据库乱码
场景一: 一台电脑上导出的sql文件到另一台电脑上恢复数据库,汉字全部是乱码,然后可能还有部分数据提示超长. 场景二: 拿到的sql文件不是原始的导出sql文件,只有表结构和表数据,出现的问题和场景一 ...
- R语言低级绘图函数-text
text函数用来在一张图表上添加文字,只需要指定对应的x和y坐标,以及需要添加的文字内容就可以了 基本用法: plot(1:5, 1:5, xlim = c(0,6), ylim = c (0,6), ...
- python PIL 库处理文件
通过PIL库提供的API接口可以很方便的处理图像,功能十分强大: 最近有一个替换png背景色的需求,替换背景色的同时又不能够覆盖原来的文字,之前利用perl 的CD 模块一直没能够正确处理,最终用PI ...